AsyncTask 意义
AsyncTask 是一个轻量级的异步类,它是使用线程池执行后台任务,并将结果传送到主线程更新UI;下面是源码的介绍:
|
|
AsyncTask的内部封装了两个线程池(SerialExecutor和THREAD_POOL_EXECUTOR)和一个Handler(InternalHandler)。
其中SerialExecutor线程池用于任务的排队,让需要执行的多个耗时任务,按顺序排列,THREAD_POOL_EXECUTOR线程池才真正地执行任务,InternalHandler用于从工作线程切换到主线程。
AsyncTask creator
声明如下:
|
|
继承 AsyncTask 必须重写它相应的方法;
|
|
方法的调用顺序:
- 需要更新进度:
上面几个方法的调用顺序:
onPreExecute() –> doInBackground() –> publishProgress() –> onProgressUpdate() –> onPostExecute()
- 不需要更新进度
onPreExecute() –> doInBackground() –> onPostExecute()
简单使用:
|
|
|
|
AsyncTask 源码
先简单的介绍一下基本属性,源码如下:
|
|
AsyncTask 的构造函数,必须初始化在UI 线程,如下:
|
|
这段代码只是初始化了 mWorker 和 mFuture 这两个变量,并将 mWorker 作为参数传到了 mFuture 中;
- 执行任务
|
|
这个 execute()方法只能顺序执行,其中 sDefaultExecutor 为上文中的 SERIAL_EXECUTOR;
|
|
|
|
SerialExecutor 内部维持了一个队列,通过锁使得该队列保证AsyncTask中的任务是串行执行的,即多个任务需要一个个加到该队列中,然后执行完队列头部的再执行下一个,以此类推。
SerialExecutor 只是为了维持任务的顺序执行,实际执行任务还是交给 THREAD_POOL_EXECUTOR;
执行完 doInBackgroudn() 方法之后,执行 postResult() 方法;
|
|
|
|
|
|
InternalHandler 是一个内部类,接收到 MESSAGE_POST_RESULT 表示执行完毕;
InternalHandler是一个静态类,为了能够将执行环境切换到主线程,因此这个类必须在主线程中进行加载。所以变相要求AsyncTask的类必须在主线程中进行加载。
|
|
Status 有三种状态,如下:
|
|
AsyncTask 的缺陷
1.)生命周期
AsyncTask不与任何组件绑定生命周期,所以在Activity/或者Fragment中创建执行AsyncTask时,最好在Activity/Fragment的onDestory()调用 cancel(boolean);
2.)内存泄漏
如果AsyncTask被声明为Activity的非静态的内部类,那么AsyncTask会保留一个对创建了AsyncTask的Activity的引用。如果Activity已经被销毁,AsyncTask的后台线程还在执行,它将继续在内存里保留这个引用,导致Activity无法被回收,引起内存泄露。
3.) 结果丢失
屏幕旋转或Activity在后台被系统杀掉等情况会导致Activity的重新创建,之前运行的AsyncTask(非静态的内部类)会持有一个之前Activity的引用,这个引用已经无效,这时调用onPostExecute()再去更新界面将不再生效。
4)串行还是并行
从上述源码分析中分析得到,默认情况下AsyncTask的执行效果是串行的,因为有了SerialExecutor类来维持保证队列的串行。如果想使用并行执行任务,那么可以直接跳过SerialExecutor类,使用executeOnExecutor()来执行任务。
到此为止,AsyncTask 的源码就分析完毕啦。