无业游民

千里之行始于足下

导航

AsyncTask的使用

AsyncTask,从字面意思去理解就是异步任务。这里可以打个不恰当的比方,A同学去批发一批货物,先去跟店家商讨价钱下订单(onPreExecute)等前期工作,A同学是个大忙人,在一家店耽搁的时间超过5秒,就活不下去了,所以A同学会在店家准备货物的这段时间(doInBackground)去忙别的生意,待店家准备好货物之后会告知A同学货物准备好了或者是没有货了,A同学正常情况下会对店家的消息作出响应(onPostExecute),在这段过程当中,有需要的话店家可以通过publicProgress及时向A同学通告准备了多少的货物。但A同学也很有可能会变卦,发现他不想要这批货物了,他就会(onCancelled), 如果A同学处事妥当的话,他应该要以某种标记来通知店家不要准备货物了,如果不通知店家的话店家会继续把货物准备到好。A同学如果不想要这批货物之后(onCancelled),他就不会再对这批货物进行任何处理(onPostExecute)了.

AsyncTask<Type1, Type2, Type3>, Type1是传递给doInBackground的参数的类型,Type2是传递给onProgressUpdate的类型,Type3是doInBackground执行完毕然后传递结果给onPostExecute的参数类型。

new一个AsyncTask,然后execute,正常情况下会先调用onPreExecute, 然后调用doInBackground,接着调用onPostExecute。如果要做一些耗时的网络操作,并且网络操作过程中或是完成后需要通过UI展现出来,用AsyncTask来做是最适合不过了。譬如下载的时候,显示下载进度用户体验可能更好些,可以在doInBackground里面通过调用publishProgress函数,publishProgress会将参数传递给onProgresUpdate,然后在onProgressUpdate里面更新UI。当下载完成之后,需要显示播放界面则可以在onPostExecute里面执行。

但是有时候总是会出现我们意想不到的情况,例如在下载的时候,这一首歌曲还没有下完,又点击了下一首,很显然,当前这首歌就不应该再继续下载了。怎么办呢,我们可以通过XXXtask.getStatus()==Status.RUNNING来判断当前任务是否仍在运行,如果仍在运行,我们就要想办法把它停掉。可以通过调用XXXtask.cancel(true),这个函数会触发onCancelled, 我们可以在onCancell里进行进一步处理,但是onCancelled虽然调用了,假如doInBackground里面的任务没有执行完,仍然会继续执行下去。如果想停止下载,可以通过在onCancell里面设置标记位isCancelled,然后在doInBackground里面每一次执行的时候都判断标记位是否为true,如果为true,则应当进行相应处理,然后返回。在执行过onCancell之后,onPostExecute是不会再执行了。

从以上的描述过程来看,doInBackground是由另外的线程来执行的,其余的方法则都是由UI线程来处理的,所以耗时的工作应该要放在doInBackground里来处理,不然会出现ANR的,当然Android里面提供的通信方式还可以是thread-handler,broadcast-service. 我屡试不爽的就是thread-handler了,用handler的消息处理机制绝对要比回调函数好用得多。

posted on 2011-11-15 00:22  PeterHuang  阅读(1891)  评论(0编辑  收藏  举报