一、简介
AsyncTask是Android系统提供的一个轻量级的异步处理机制,使用AsyncTask可以方便的执行异步任务,并将结果反馈到UI线程中。AsyncTask是使用Handler来实现不同线程之间的交互的
二、基本用法
public abstract class AsyncTask<Params, Progress, Result> {
}
通过上面的代码可以看出AsyncTask是一个抽象类,使用过程中一般需要定义一个子类去继承它,在继承时需要指定3个泛型参数:
- Params:在执行AsyncTask时需要传入的参数。
- Progress:后台任务执行的百分比。
- Result:后台执行任务最终返回的结果。
一个异步任务的执行一般包含以下几个步骤:
- execute(Params params); 触发异步任务的执行。
- onPreExecute(); 在execute()被调用以后立刻执行,一般是在执行异步任务前对UI进行标记。
- doInBackground(Params ...); 在onPreExecute()完成以后立刻执行,用于执行比较耗时的操作,在执行的过程中不能直接操作UI,但是可以通过pulishProgress(Progress...)来反馈任务的进度到UI线程。
- onProgressUpdate(Progress); 在doInBackground() 执行完成以后,会自动调用该方法。该方法运行在UI线程中,主要是将任务执行的进度更新在UI线程中。
- onPostExecute(Result); onPostExecute运行在UI线程中,当doInBackground()运行完成后,它会调用该方法将Result反馈到UI界面上。(当后台任务执行完毕并通过return语句进行返回时,这个方法就很快会被调用。返回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些UI操作。)
简单来说,使用AsyncTask的诀窍就是,在doInBackground()方法中执行具体的耗时任务,在onProgressUpdate()方法中进行UI操作,在onPostExecute()方法中执行一些任务的收尾工作。其中一个异步任务中最少需要重写doInBackground(Params ...)和onPostExecute(Result)这两个方法。
使用AsyncTask类,必须遵守以下几条准则:
- Task实例必须在主线程中创建;
- execute()必须在主线程中调用;
- AsyncTask中重写的四个方法都是自动调用的,不能手动调用。
- 一个task只能执行一次。
使用AsyncTask需要注意的是,AsyncTask的生命周期不受activity的影响,所以容易造成内存泄漏。
原因:
在activity中调用task,则task持有activity的引用。当activity关闭时,task并没有执行完成。此时activity的引用得不到释放,就会出现内存泄漏的情况。
解决方法:
①将AsyncTask设置为static,设置为静态对象后,在Activity类初始化的时候会初始化,会占用一定的内存,但是会和Activity同生命周期,Activity销毁时AsyncTask也会被销毁。
②使用弱引用,这样gc运行时就会回收,避免内存泄漏。