解读AsyncTask
要点:AsyncTask主要用于short operations (a few seconds at the most.)。如果你需要“running for long periods of time”,官方推荐使用various APIs provided by the java.util.concurrent pacakge such as Executor, ThreadPoolExecutor and FutureTask.
关于该类的三个泛型:
Params, the type of the parameters sent to the task upon execution.
Progress, the type of the progress units published during the background computation.
Result, the type of the result of the background computation.
第一个为传入参数,第二个为progress的类型,第三个为返回结果。
该类四个方法的执行顺序以及要点分别为:
onPreExecute():运行在 UI thread。
doInBackground(Params...):运行在后台线程,过程之中可使用publishProgress方法输出过程。
onProgressUpdate(Progress...):运行在UI线程。
onPostExecute(Result):运行在UI线程。
而关于取消操作,使用cancel(boolean),使用该方法之后,在doInBackground之后的不再是onPostExecute而是 onCancelled(Object),因此,为了做无用功,尽可能在doInBackground里通过isCancelled()确定当前状态。
Threading rules
There are a few threading rules that must be followed for this class to work properly:
- The AsyncTask class must be loaded on the UI thread. This is done automatically as of
JELLY_BEAN
.- The task instance must be created on the UI thread.
execute(Params...)
must be invoked on the UI thread.- Do not call
onPreExecute()
,onPostExecute(Result)
,doInBackground(Params...)
,onProgressUpdate(Progress...)
manually.- The task can be executed only once (an exception will be thrown if a second execution is attempted.)
还有几个守则必须遵守:
AsyncTask必须在UI线程里读取,必须在UI线程里实例化,execute必须在UI线程里调用,任务只能调用一次。
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 indoInBackground(Params...)
.- Set member fields in
doInBackground(Params...)
, and refer to them inonProgressUpdate(Progress...)
andonPostExecute(Result)
.
关于同步操作。
Order of execution
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with
DONUT
, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting withHONEYCOMB
, tasks are executed on a single thread to avoid common application errors caused by parallel execution.If you truly want parallel execution, you can invoke
executeOnExecutor(java.util.concurrent.Executor, Object[])
withTHREAD_POOL_EXECUTOR
.
在1.6开始,所有的任务使用线程池来搞定,而在3.0开始之后,只是用单线程,来避免各种错误。
如果还是希望使用并行的操作,请使用executeOnExecutor(java.util.concurrent.Executor, Object[]) with THREAD_POOL_EXECUTOR.