AsyncTask类原型
public abstract class AsyncTask<Params, Progress, Result>
- Params:传递给AsyncTask的类型,作为doInBackground的参数类型
- Progress:作为onProgressUpdate和publishProgress的参数类型
- Result:由doInBackground返回,作为onPostExecute的参数类型
使用规则
- 该类实例必须在UI线程中创建
- execute方法必须在UI线程中调用
- 一个任务实例只能执行一次
执行流程
- onPreExecute:在UI线程中执行,一般用于任务执行前初始化UI,如显示进度条对话框等
- doInBackground:在后台执行,期间可以调用publishProgress来更新进度条等内容
- onProgressUpdate:当publishProgress调用时在UI线程中执行,可更新进度条或显示文本等信息
- onPostExecute:在UI线程中执行,可以利用返回的结果更新UI,或者关闭进度条对话框等。
- onCanceled: 该方法运行在UI线程中,可以在方法中关闭进度条对话框等。
任务的取消
可以调用cancel取消任务,之后isCancelled会返回true。
取消任务后,doInBackground返回后,onPostExecute不再执行,而是onCancelled执行。
为了尽快取消任务,应该在doInBackground中调用isCancelled检查任务是否取消,以采取相应的行动。
在编写doInBackground方法时,应该不时地检查isCanceled的返回值,如果返回true,应该停止执行任务。
在onPostExecute中,应该调用isCanceled检测任务是否已经被取消。
另外,在调用execute执行后,应该注意它的取消操作。
例如在Activiy中,应该在Activity不可见时(onStop方法)取消操作。
当配置变化时
当配置变化时,如果进行了合适的取消,当Activity或Fragment重新启动时,会导致任务重新开始。
为了避免在配置变化时重新开始,可以把AsyncTask保存在Fragment中,当配置变化时,使用Fragment保证任务不会中断。
如果在执行任务时,同时显示了加载对话框,可以在配置变化时,dismiss对话框,当重新开始时,再显示对话框。
http://blog.csdn.net/lmj623565791/article/details/37936275
AsyncTask的适用场景和内存泄漏
AsyncTask应该用于短时间的任务。
如果作用于长时间的任务,且是内部类,那么保存了Activity的引用,会导致Activity不会被垃圾回收。可以通过静态类来解决。
同时,在更新UI时,会抛出异常。可以通过实现合适的取消机制来解决。
实现原理
为了实现可取消的操作,内部使用了FutureTask类。
同时,内部使用了线程池,默认情况下,只有一个任务在执行,其他任务会入队列等待执行。可以通过构造方法,传递自定义的Executor来并行执行。
-在Android 3.0之前,线程池可以并行执行5个任务,最大为128.
在Android 3.0及其之后,默认线程池为串行执行。
最后,为了能够更新UI,使用可扩展了Handler的静态内部类,它的Looper使用的是UI线程的。所以,可以发送消息给该Handler以更新进度条和UI等。
另外,根据源码可知,调用execute后,onPreExecute在调用线程中执行,所以AsyncTask必须在UI线程中执行。
因为AsyncTask中有些方法是根据调用线程来作为参数,所以AysncTask应该在UI线程中创建。
至于一个AsyncTask只能执行一次,我想可能是因为如果允许执行多次的话,如果线程池为多个线程并行执行,那么我们在扩展该类时,必须考虑线程同步的问题,这样就有点麻烦了。
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
...
onPreExecute();
exec.execute(mFuture);
return this;
}