首先异步任务做的做多的用来更新UI,至于怎样来跟UI线程进行交互的,我们从源码看起。当我们new AsyncTask<Params, Progress, Result>.execute(),时,会执行AsyncTask的构造方法,然后执行execute()方法。我们来看看构造方法:
WorkerRunnable是一个抽象内部类,implements一个interface,call()方法是在接口中定义的。我们需要注意的是它return的地方,postResult(doInBackground(mParams))。doInBackground(mParams),我们太熟悉了,这里面执行耗时操作,返回一个result作为onPostExecute(Object result)的参数。我们来看一下postResult()方法里做了什么
好吧,这里面,我们也很熟悉。这是message对消息进行封装。sendToTarget()方法中有一行代码,target.sendMesaage(this),毫无疑问,这个target就是Handler的实例。所以,call()方法中执行了doInBackground()方法,并通过handler发送了MESSAGE_POST_RESULT的消息。那接下来我们看看handler接收消息做了什么:
从上面的代码,可以看出,Hander接收消息后,执行了onPostExecute()方法,这个方法我们同样很熟悉。构造方法我们看到这,接下来我们看看AsyncTask类中excute()方法中执行了哪些操作。
execute()方法中执行了executeOnExecutor()方法,我们来看看这个方法里做了什么。首先,状态改为RUNNING,保证每个AsyncTask实例只执行一次,android3.0以后默认采用单线程模式。oPreExecute()这个方法我们也很熟悉,一般用来显示进度条的。mWorker.mParams = params。mWorker是WorkerRunnable的实例。WorkerRunnable是一个抽象的内部类,实现Callable接口,定义了一个mParams变量。毫无疑问,为call()方法中的doInBackground()方法的参数传值。最后是,exec.execute(mFuture).
mTasks是个存放Runnable的队列,scheduleNext()执行线程池中的线程。重点来看r.run(),r是执行excute()方法传递的参数,这个参数是mFuture,是FutureTask的实例。看看run()里面做了什么:
run()方法调用内部类Sync中的innerRun()方法,这个方法中我们来看被标记的这行代码。这里callable是WorkerRunnable的对象,执行了WorkerRunnable继承的接口Callable中的call()方法。我们知道call()方法的返回值是postResult(doInBackground(mParams)),这个上面已经介绍过了。好了,似乎一切线索都串联起来了。
简单来总结一下,当我们执行new AsyncTask(Params,Progress,Result).excute()时,AsyncTask的构造方法实现了Callable接口中的call()方法,然后excute()方法中执行了onPreExecute()方法,调用了call()方法,执行了doInBackGground()方法,返回值result被message封装,并且对message的状态设为MESSAGE_POST_RESULT,通过handler发送出去。handlerMessage()接收到消息后,先对message的状态值进行判断,执行相应操作。这里返回的是MESSAGE_POST_RESULT,对应的finish()方法中执行了onPostExecute()方法。我们可以在onPostExecute()方法中添加对UI的操作。