1、AsyncTask是什么?
本质上是封装了 线程池和 Hanlder的异步框架。
2、AsyncTask的基本用法
主要有:3个泛型参数 + 4个方法。
下面以下载一个图片为例:
3个泛型:AsyncTask<Params, Progress, Result>
Params:这个泛型指定的是我们传递给异步任务执行时的参数的类型。
Progress:这个泛型指定的是我们的异步任务在执行的时候将执行的进度返回给UI线程的参数的类型。
Result:这个泛型指定的异步任务执行完后返回给UI线程的结果的类型。
额外:如果三个泛型不设置,全都变成 AsyncTask <Void, Void, Void>。
4个步骤:
onPreExecute(): 这个方法是在执行异步任务之前的时候执行,并且是在UI Thread当中执行的,通常我们在这个方法里做一些UI控件的初始化的操作,例如弹出要给ProgressDialog。
doInBackground(Params… params): 在onPreExecute()方法执行完之后,会马上执行这个方法,这个方法就是来处理异步任务的方法,Android操作系统会在后台的线程池当中开启一个worker thread来执行我们的这个方法,所以这个方法是在worker thread当中执行的,这个方法执行完之后就可以将我们的执行结果发送给我们的最后一个 onPostExecute 方法,在这个方法里,我们可以从网络当中获取数据等一些耗时的操作。
onProgressUpdate(Progess… values): 这个方法也是在UI Thread当中执行的,我们在异步任务执行的时候,有时候需要将执行的进度返回给我们的UI界面,例如下载一张网络图片,我们需要时刻显示其下载的进度,就可以使用这个方法来更新我们的进度。这个方法在调用之前,我们需要在 doInBackground 方法中调用一个 publishProgress(Progress) 的方法来将我们的进度时时刻刻传递给 onProgressUpdate 方法来更新。
onPostExecute(Result… result): 当我们的异步任务执行完之后,就会将结果返回给这个方法,这个方法也是在UI Thread当中调用的,我们可以将返回的结果显示在UI控件上。
3、AsyncTask机制原理
1)本质是一个静态的线程池,AsyncTask派生的子类可以实现不同的异步任务,这些任务都是提交到静态的线程池中执行。
2)线程池中的工作线程执行 doInBackground(mParams)方法执行异步的任务。
3)当任务状态改变后,工作线程向UI线程发送消息,AsyncTask内部的InternalHandler响应这些消息,并调用相关的回调函数。
4、AsyncTask注意事项:
1)内存泄露:
静态内部类持有外部类的匿名引用,导致外部对象无法得到释放,解决方法很简单,让内部持有外部的弱引用即可解决。
2)生命周期:
在Activity的onDestory()中及时对AsyncTask进行回收,调用其cancel()方法来保证程序的稳定性。
3)结果丢失:
当内存不足时,当前的Activity被回收,由于AsyncTask持有的是回收之前Activity的引用,导致AsyncTask更新的结果对象为一个无效的Activity的引用,这就是结果丢失。
4)并行或串行:
1.6(Donut)之前: 在第一版的AsyncTask,任务是串行调度。一个任务执行完成另一个才能执行。由于串行执行任务,使用多个AsyncTask可能会带来有些问题。
1.6-2.3: 所有的任务并发执行,这会导致一种情况,就是其中一条任务执行出问题了,会引起其他任务出现错误。
3.0之后AsyncTask又修改为了顺序执行,并且新添加了一个函数executeOnExecutor(Executor),如果您需要并行执行,则只需要调用该函数,并把参数设置为并行执行即可。
参考资料:
网友评论