先把AsyncTask的基本用法熟悉一遍
class MyAsyncTask extends AsyncTask<Void, Integer, String> {
@Override
protected void onPreExecute() {
//準(zhǔn)備一些初始化操作
}
@Override
protected String doInBackground(Void... params) {
//后臺操作
}
@Override
protected void onProgressUpdate(Integer... values) {
//更新進(jìn)度
}
@Override
protected void onPostExecute(String s) {
//得到后臺操作返回的結(jié)果
}
}
new MyAsyncTask().execute();
Void,Integer,String三個(gè)類型分別是在做后臺操作時(shí)傳入的參數(shù), 更新的進(jìn)度, doInBackground操作里返回的結(jié)果陈醒。
上面就是基本的用法,接下來進(jìn)入正題分析AsyncTask的源碼.
首先我們new了一個(gè)MyAsyncTask的實(shí)例借跪。那么AsyncTask的源碼里做了什么呢产雹?
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
return postResult(doInBackground(mParams));
}
};
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
try {
postResultIfNotInvoked(get());
} 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);
}
}
};
}
可以看出是實(shí)例化了一個(gè)WorkerRunnable對象,一個(gè)FutureTask對象锻霎。我們先不管這2個(gè)對象有什么用。細(xì)心的同學(xué)可以發(fā)現(xiàn)call()這里調(diào)用了doInBackground方法。這里的疑問我們先放下。
然后看我們new完一個(gè)MyAsyncTask后我們執(zhí)行了execute()方法瓤狐。我們到源碼了看execute()執(zhí)行了什么瞬铸。
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
就一段代碼,
我們看到底 executeOnExecutor方法里到底執(zhí)行了什么础锐。
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;
}
看到這里我們有點(diǎn)眉目了嗓节,onPreExecute()方法露面了,確實(shí)是onPreExecute()最先執(zhí)行皆警。
然后我們看到 exec.execute(mFuture)這段代碼拦宣。這里顯然可以看出sDefaultExecutor執(zhí)行了execute方法。繼續(xù)努力信姓,找出sDefaultExecutor的execute方法鸵隧。我們發(fā)現(xiàn)這個(gè)sDefaultExecutor其實(shí)就是實(shí)現(xiàn)了Executo的execute接口。
private static class SerialExecutor implements Executor {
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
Runnable mActive;
public synchronized void execute(final Runnable r) {
mTasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (mActive == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
r.run()的r就是上面的mFuture意推。還記得我在文章開頭說的WorkerRunnable對象豆瘫,F(xiàn)utureTask對象嗎?在創(chuàng)建AsyncTask的時(shí)候就已經(jīng)實(shí)例化了mFuture菊值。所以這里
其實(shí)就是執(zhí)行了mFuture的run方法外驱。那么問題來了,在哪里能看出run方法里做了什么鬼東西呢?首先我們可以看出mFuture是一個(gè)FutureTask對象,我們來看看他的構(gòu)造函數(shù)
public
FutureTask(Callable<V> callable) {
}
在實(shí)例化的時(shí)候
mFuture = new FutureTask<Result>(mWorker)
而WorkerRunnable又實(shí)現(xiàn)了Callable這個(gè)接口.
講到這里大家或許已經(jīng)明白了,run方法里執(zhí)行的是mWorker里的call() 方法腻窒。
而在call() 方法里有這樣的一段代碼
return postResult(doInBackground(mParams));
哈哈,doInBackground出現(xiàn)了昵宇。這里的mParams就是我們傳入的參數(shù),并且返回了postResult的返回值。那postResult又是什么呢儿子?
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
沒錯(cuò)你沒有看錯(cuò),其實(shí)AsyncTask內(nèi)部也是通過Handler來進(jìn)行線程間通信的瓦哎。在這里我們可以看到在doInBackground返回結(jié)果后postResult通過Handler發(fā)送了一個(gè)MESSAGE_POST_RESULT消息。getHandler()返回的就是這個(gè)InternalHandler柔逼。
private static class InternalHandler extends Handler {
public InternalHandler() {
super(Looper.getMainLooper());
}
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg) {
AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
// There is only one result
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
然后我們看在處理MESSAGE_POST_RESULT消息時(shí)做了這樣的一件事情
result.mTask.finish(result.mData[0]);
繼續(xù)看源碼
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);
}
mStatus = Status.FINISHED;
}
哈哈豁然開朗啊, 出現(xiàn)了 onPostExecute,可以看到在這里把doInBackground的返回值給了onPostExecute蒋譬。然后把狀態(tài)設(shè)置為 Status.FINISHED
講到這里基本的流程都已經(jīng)講完了,但是我想糾正網(wǎng)上大多是的帖子關(guān)于這個(gè)AsyncTask其實(shí)就是Thread和Handler的結(jié)合的說法。更準(zhǔn)確的說法是FutureTask和Handler的結(jié)合卒落。為什么羡铲?
因?yàn)門hread的run方法返回值是void。而我們看AsyncTask的源碼里的call() 方法里是返回了后臺操作結(jié)果,我們再看儡毕,源碼里有這樣的一個(gè)方法
postResultIfNotInvoked(get());
而這個(gè)get()我們看
public final Result get() throws InterruptedException, ExecutionException {
return mFuture.get();
}
其實(shí)就是返回了FutureTask的執(zhí)行結(jié)果,也就是call()方法返回結(jié)果也切。
因此用Thread是達(dá)不到這種要求的。
基本流程大概就是這樣腰湾。謝謝各位看官雷恃,歡迎拍磚!7逊弧倒槐!