AsyncTask使用及實現原理 二

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章