AsyncTask可以轻松正确的使用UI线程,
这个类允许你在后台操作,
并且不需要使用threads或者handler将结果发布到UI线程。
AsyncTask设计之初就是辅助Thread和Handler的,
并且不会生成线程。
AsyncTask应该被用于短时间内的操作(最多几秒钟),
如果你想要长时间保持线程运行,
请使用Executor或者ThreadPoolExecutor或者FutureTask。
AsyncTask在后台运行任务,
在UI线程发布结果,
定义三个参数,Params, Progress和Result,
执行四个步骤,onPreExecute, doInBackground, onProgressUpdate和onPostExecute。
使用方法
AsyncTask必须被继承来使用。子类必须实现至少一个方法(ddoInBackground(Params…)),
还有一个最常用的方法(onPostExecute(Result)。
1 | private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { |
启动异步任务:1
new DownloadFilesTask().execute(url1, url2, url3);
AsyncTasks的范型参数
异步任务使用的参数是:
- Params, 启动任务时传入的参数
- Progress, 在后台任务执行时发布到UI线程的进度类型
- Result, 后台任务执行完成的结果
这三个参数不一定非要指定,可以使用Void来传入空值。1
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
4个步骤
- onPreExecute(),在应用程序执行前在UI线程上调用。
这步通常被用来准备任务开始,例如显示一个进度条。 - doInBackground(Params…),在onPreExecute()方法被调用后立即执行此方法,用来执行长时间的任务。
参数会在这一步传入,最后的结果必须返回。
在这步页可以使用publishProgress(Progress...)
来发布进度,
这些值时在UI线程中发布的,在onProgressUpdate(Progress...)
接收。 - onProgressUpdate(Progress…), 在
publishProgress(Progress...)
方法调用后在UI线程调用此方法。
执行时间未定义。
该方法用于在后台计算仍在执行时,用户界面中显示的进度。
例如,它可以用于对进度条进行动画处理或在文本字段中显示日志。 - onPostExecute(Result),在后台计算完成后在UI线程上调用。 后台计算的结果作为参数传递给该步骤。
取消异步任务
任何时候都可以通过调用cancel(boolean)
方法来取消任务。
调用此方法将导致对isCancelled()
的后续调用返回true。
调用此方法后,onCancelled(Object)
,而不调用onPostExecute(Object)
为了尽可能快地取消任务,应该始终从doInBackground(Object [])
中定期检查isCancelled()
的返回值(如果可能的话)。
线程规则
- 必须在UI线程上加载AsyncTask类。
- 必须在UI线程上创建任务实例。
- 必须在UI线程上调用execute(Params …)
- 不要手动调用onPreExecute(),onPostExecute(Result),doInBackground(Params …),onProgressUpdate(Progress …)。
- 该任务只能执行一次(如果尝试第二次执行,将抛出异常)。
内存监控
AsyncTask保证所有回调调用都是同步的,使得以下操作在没有显式同步的情况下是安全的。
- 在构造函数或onPreExecute()中设置成员字段,并在doInBackground(Params …)中引用它们。
- 在doInBackground(Params …)中设置成员字段,并在onProgressUpdate(Progress …)
和onPostExecute(Result)中引用它们。
执行顺序
首次引入时,AsyncTasks在单个后台线程上串行执行。
从DONUT开始,这被更改为一个允许多个任务并行操作的线程池。
从HONEYCOMB开始,任务在单个线程上执行,以避免并行执行引起的常见应用程序错误。
如果真的需要并行执行,则可以使用THREAD_POOL_EXECUTOR调用
executeOnExecutor(java.util.concurrent.Executor,Object [])。