尊重原创作者,转载请注明出处:
http://blog.csdn.net/gemmem/article/details/8957111
AsyncTask是一个抽象类,我们需要继承这个类,并实现抽象方法,在这个类的实现过程中需要定义3个类和执行4个方法。3个类分别是:
1.Params:执行异步任务需要的参数
2.Progress:异步任务后台执行中需要刷新的参数
3.Result:后台任务执行完毕需要返回的结果
当一个异步的任务执行,会执行4个方法,分别是:
1. onPreExecute():在异步任务调用之前,由UI线程中调用。通常用于异步任务的准备工作。
2. doinBackground(Params …):在上一步执行完毕后立即执行。是比较耗时的一步,也是由这步传入参数Params。在这里不仅可以产生最后的结果result,而且能调用publishProgress(Progress...)刷新UI
3. onProgressUpdate(Progress...): 在第二步中调用publishProgress()之后,UI线程则会调用此方法。举个例子,就像你先在异步的线程中传入UI线程的handler,当执行的过程中,你可以通过消息机制向主线程发送消息,来更新UI。而publishProgress就是发送消息,主线程就会调用onProgressUpdate。
4. onPostExecute(Result): 当异步的任务执行完毕之后,由UI线程调用。在这个方法中可以得到最终的异步结果。
本文主要讲解这4个回调函数的调用流程,
首先看构造函数:
public AsyncTask() { mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); return postResult(doInBackground(mParams)); } }; mFuture = new FutureTask<Result>(mWorker) { @Override protected void done() { try { final Result result = get(); postResultIfNotInvoked(result); } catch (InterruptedException e) { android.util.Log.w(LOG_TAG, e); } catch (ExecutionException e) { throw new RuntimeException("An error occured while executing doInBackground()", e.getCause()); } catch (CancellationException e) { postResultIfNotInvoked(null); } catch (Throwable t) { throw new RuntimeException("An error occured while executing " + "doInBackground()", t); } } }; }
mFuture是一个FutureTask,这个FutureTask使用Callable作为构造函数的参数,并实现了done( )方法。
再来看看AsyncTask的execure(Param...)方法:
public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) { if (mStatus != Status.PENDING) { switch (mStatus) { case RUNNING: throw new IllegalStateException("Cannot execute task:" + " the task is already running."); case FINISHED: throw new IllegalStateException("Cannot execute task:" + " the task has already been executed " + "(a task can be executed only once)"); } } mStatus = Status.RUNNING; onPreExecute(); mWorker.mParams = params; exec.execute(mFuture); return this; }现在从execute开始分析:
1、execute调用executeOnExecutor
2、executeOnExecutor调用onPreExecute
3、随后执行:exec.execute(mFuture)
4、mFuture被执行后,mWorker的call()开始执行
5、call()里面调用doInBackground()
6、doInBackground()执行完成后,会执行postResultIfNotInvoked(result),再执行postResult()
7、postResult导致主线程执行result.mTask.finish(result.mData[0])
8、finish()会调用onPostExecute()
至此,4个回调方法中的3个已经讲完了。
还剩下onProgressUpdate(),其实onProgressUpdate()的执行是被动的,所以不在上面的分析之中,它的执行需要app去调用publishProgress。
app一般会在doInBackground()中的循环中执行publishProgress,这样就回调到onProgressUpdate,而onProgressUpdate()一般被实现为更新UI的函数。
至此4个函数都分析到了,如果读者对Callable和FutureTask不是很理解,请阅读我的上一篇文章:Java FutureTask理解