AsyncTask浅析

首先需要知道的一点是AsyncTask可以便于我们进行后台操作(读取网络数据,查询数据库等),并且可以将操作的结果返回给UI线程。该类应该用于处理时间较短的操作(至多几秒钟的操作),如果需要在后台处理消耗大量时间的操作,应该使用java.util.concurrent包中的内容,例如Executor,ThreadPoolExecutor和FutureTask等等。

该类主要用来使用一个新的线程(该线程由该类内部实现,我们无需关心具体实现,但需知道其基本原理)执行一系列的运行在后台的操作,并且将其发送给UI线程。要使用该类需要定义3个数据类型,分别是Params,Progress和Result;之后需要重写该类的回调方法(doInBackground必须重写),分别是:onPreExecute,doInBackground,onProgressUpdate和onPostExecute(还有其他一些方法,这几个方法比较常用),最后实例化继承该类的子类(或匿名内部类)调用该类的execute方法来启动该任务。
代码示例如下(摘自API):
定义该类时:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }
要开启该任务时:
new DownloadFilesTask().execute(url1, url2, url3);
关于这三个参数的解释:
1.Params  该类型是指你要从UI线程中放到AysncTask中处理的参数,上例中的类型是URL,指的是doInBackground()里形参的类型,你将该类型的值放到execute中,就是doInBackground()里所接收到的实参(如上例的具体实参是url1, url2, url3,在doInBackground的形参urls接收的就是这三个参数)。
2.Progress 该类型指的是你调用publishProgress()时传入的参数类型,将该类型的参数传入到publishProgress()后(在doInBackground中确定参数值是什么)该参数会被传到onProgressUpdate()中,在onProgressUpdate()中对该函数进行处理(比如设置UI线程的ProgressDialog的progress值)。
3.Result 该类型是指你想要在AsyncTask数据处理完毕后想要得到的结果的类型,该例中的类型是long,该值将通过doInBackground()的返回值返回到onPostExecute()的形参中。
注:上面的三个参数的类型均可以为Void,代表不需要处理该参数。
上例中的4个函数的主要执行步骤:
通过这4个方法,我们可以做到:从UI线程得到数据,在异步任务中处理数据,在UI线程中得到处理的结果并处理结果。
onPreExcute(),该方法在任务执行之前被UI线程调用(注意,是UI线程),该方法通常用来做一些任务执行开始之前的初始化工作,一般也用来在用户界面显示一个ProgressBar或其他View来在处理数据时让用户体验更好。
doInBackground(),该方法是该类的核心方法,首先它在onPreExcute执行后调用了后台的线程,在该方法里面主要由开发者编写代码来处理后台费时的操作(从网络读取数据,查询数据库,从文件中读取数据等),通过从UI线程传进来的参数,计算出结果(如果需要结果,必须在该步计算出结果),该结果通过return语句将返回到onPostExecute()方法中。在该方法中也可以调用publishProgress()来到一个或多个的progress参数传入onProgressUpdate()中。(该方法运行在异步线程)
onProgressUpdate(),在publishProgress()调用后,该方法将被调用(在UI线程执行),用得到的progress值方便修改UI界面上的各类Progress相关控件的progress值或者更新log信息等等。
onPostExecute() 在doInbackground()执行完后,该方法将在UI线程被调用,并且得到从doInbackground()方法中处理所得到的的结果。

取消AsyncTask  可以调用cancel()方法来取消该任务,通过isCancelled()函数来确定是否已经取消了该任务,调用该方法后,同样需要执行完doInBackground()方法,但是在执行完该方法后,将不会执行onPostExecute()方法,而是调用onCancel()方法(它也运行在UI线程)来接收处理的结果。如果需要在doInBackground()执行过程中取消该task,应该在doInBackground()中时刻检查isCancelled()方法,来退出该函数(直接return或break循环之类的)

补充:
1.AsyncTask实例必须在UI线程中被创建和执行。class必须在UI线程中被加载。
2.任务只能被执行一次,多次执行将抛出异常。
3.不要手动调用相关的回调方法(例如onPreExecute(),onPostExecute()等)

参考资料:Android API文档
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值