AsyncTask是如何更新進度
上一篇我們講了AsyncTask 的基本使用及原理分析,但是篇幅有點長了,最後沒有介紹在執行異步任務時是如何更新進度的。這篇我們接着上一篇繼續介紹AsyncTask是如何跟新進度的。
在這之前我們先來介紹進度執行及更新的兩個方法。
/**
* 任務的執行進度
* @param values
*/
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
這個是進度的監聽方法,再看下進度的執行方法。
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}
這個方法是要放在異步執行方法中來執行的,也就是在doInBackground 方法中調用publishProgress方法將進度參數寫入,然後onpProgressUpdate方法就會執行。大概流程就是這樣,下面我們來看publishProgress具體是如何來實現的。
isCancelled() 用來判斷當前任務是否取消了,如果沒有取消,則通過handler方法發送消息。
public final boolean isCancelled() {
return mCancelled.get();
}
那麼又是如何判斷任務取消的,只要知道mCancelled 在哪裏set值就能找到了,它本身是AtomicBoolean 變量名,借用別人的一些理解 AtomicBoolean :其基本的特性就是在多線程環境下,當有多個線程同時執行這些類的實例包含的方法時,具有排他性,即當某個線程進入方法,執行其中的指令時,不會被其他線程打斷,而別的線程就像自旋鎖一樣,一直等到該方法執行完成,才由JVM從等待隊列中選擇一個另一個線程進入。接着看:
public final boolean cancel(boolean mayInterruptIfRunning) {
mCancelled.set(true);
return mFuture.cancel(mayInterruptIfRunning);
}
也就是說當我們調用了cancel方法後該任務將會被取消。扯的有點遠了,我們回到主幹上publishProgress方法。
這個時候它會通過handler發送一條消息,MESSAGE_POST_PROGRESS,上一篇我們講過,asyncTask內部是內置了handler的,並且獲取的是主線程的looper。
簡單看下AsyncTaskResult類
private static class AsyncTaskResult<Data> {
final AsyncTask mTask;
final Data[] mData;
AsyncTaskResult(AsyncTask task, Data... data) {
mTask = task;
mData = data;
}
}
它是一個內部私有類,有兩個參數,一個是AsyncTask 一個是自定義類型泛型數組Data,通過new 這個類將參數放在其中,通過handler發送消息,接收到消息後再將msg.obj轉爲AsyncTaskResult<?>,實現主線程和ui線程切換。
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;
}
}
result.mTask.onProgressUpdate(result.mData); 通過重寫AsyncTask 的onProgressUpdate方法實現進度更新。
這樣我們就可以實現異步任務進度更新工作了。
https://blog.csdn.net/zmx729618/article/details/52767736