Overview
AsyncTask 能够让我们不用操作 threads 和 handlers 的情况下,在 UI 线程中方便的执行耗时操作,并且返回结果到 UI 线程。
AsyncTask 理论上被用来执行 短时(通常情况下,只需几秒的操作)的操作。如果你需要长时间的执行某一操作,强烈推荐你使用 java.util.concurrent 包下的 Executor, ThreadPoolExecutor 和 FutureTask.
你在定义AsyncTask时需要定义三个泛型参数:
- Called Params - 传入的参数
- Progress - 执行中的参数
- Result - 返回值参数
4 个方法:
如何使用?
AsyncTask 必须作为一个子类去使用。其中, doInBackgournd(Params...) 是必须实现的方法,大部分情况下,我们还需要实现 onPostExecute(Result) 方法.
下面是一个使用的例子:
1 | private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { |
然后,就是执行这个 AsyncTask:
1 | new DownloadFilesTask().execute(url1, url2, url3); |
AsyncTask 的泛型参数
- 1.
Params执行前传入的参数 - 2.
Progress执行中传入的参数 - 3.
Result执行完毕后返回的参数
当然,如果你不需要传任何参数,使用 Void 即可:
1 | private class MyTask extends AsyncTask<Void, Void, Void> { ... } |
四个方法
- 1.
onPreExecute()UI线程会在任务执行前调用此方法。通常被用来设置与任务相关的操作,比如在用户界面显示一个进度条。 - 2.
doInBackground(Params...)在onPreExecute()执行完毕后,调用此方法,注意,此耗时操作执行在一个后台线程中。Params参数会被传入到此方法中,计算的结果必须由这一步返回,并将传回最后一步。在方法中,我们还可以调用publishProgress(Progress...)来传递进度,然后我就可以在onProgressUpdate(Progress...)的方法中来更新 UI 了。 - 3.
onProgressUpdate(Progress...)此方法将会在调用了publishProgress(Progress...)后,由UI线程来调用。通常被用来在界面上显示执行的进度,例如,它可用于动画显示一个进度栏或在文本字段中显示日志。 - 4.
onPostExecute(Result)此方法在耗时操作执行完毕后,由UI线程调用。doInBackground(Params...)中返回的结果将作为参数传递进来。
取消任务
我们可以通过调用 cancel(boolean) 在任何时候来取消异步任务。Invoking this method will cause subsequent calls to isCancelled() to return true. After invoking this method, onCancelled(Object), instead of onPostExecute(Object) will be invoked after doInBackground(Object[]) returns. To ensure that a task is cancelled as quickly as possible, you should always check the return value of isCancelled() periodically from doInBackground(Object[]), if possible (inside a loop for instance.)
使用它,你需要遵守
- The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
- 你必须在 UI 线程中创建任务实例。
- 你必须在 UI 线程中调用
execute(Params...) - 不要手动调用
onPreExecute(),onPostExecute(Result),doInBackground(Params...),onProgressUpdate(Progress...) - 任务只能执行一次(如果你尝试调用第二次,将会抛出异常)
Memory observability
AsyncTask guarantees that all callback calls are synchronized in such a way that the following operations are safe without explicit synchronizations.
- Set member fields in the constructor or onPreExecute(), and refer to them in doInBackground(Params…).
- Set member fields in doInBackground(Params…), and refer to them in onProgressUpdate(Progress…) and onPostExecute(Result).
执行顺序
在第一次引入 AsyncTask 时,内部实现使用串行执行单个后台线程。而从 DONUT(甜甜圈)开始,这是更改为允许多个任务并行运行的线程池。从 HONEYCOMB(蜂窝)开始,在单个线程上执行任务并行执行,以避免引起的常见的应用程序错误
如果你真的需要并行执行, 你可以通过 THREAD_POOL_EXECUTOR 来调用 executeOnExecutor(java.util.concurrent.Executor, Object[]) .
本文参考:
http://developer.android.com/reference/android/os/AsyncTask.html