AsyncTask原理

AsyncTask原理

new AsyncTask<String, String, String>() {

    // 2. 運行在主線程中, 做一些準備操作.
    public void onPreExecute() {

    }

    // 3. 運行在子線程中, 做一些耗時的任務.
    public String doInBackground(String... params) {
        return null;
    }

    // 4. 運行主線程中, result就是doInBackground方法返回的值. 做一些收尾操作.
    public void onPostExecute(String result) {

    }
}.execute(String... params);    // 1. 開始執行異步任務.

AsyncTask的execute的方法, 代碼如下:

public final AsyncTask<Params, Progress, Result> execute(Params... params) {
    ...

    mStatus = Status.RUNNING;

    // 調用用戶的實現方法, 讓用戶做一些準備操作. 運行在主線程中.
    onPreExecute();

    // 把mWorker中的mParams賦值爲用戶傳遞進來的參數.
    mWorker.mParams = params;
    // 使用線程池, 執行任務. 這時進入到子線程中.
    sExecutor.execute(mFuture);

    return this;
}

查看mWorker的初始化過程, 代碼如下:

// AsyncTask構造函數在一開始使用異步任務時, 已經調用.
public AsyncTask() {
    mWorker = new WorkerRunnable<Params, Result>() {
        public Result call() throws Exception {
            ...
        }
    };

    // 1. 把mWorker對象傳遞給了FutureTask的構造函數
    mFuture = new FutureTask<Result>(mWorker) {
        @Override
        protected void done() {
            ...
        }
    };
}

// FutureTask類中接收的是Callable的類型, 其實WorkerRunnable類型實現了Callable的類型.
public FutureTask(Callable<V> callable) {
    if (callable == null)
        throw new NullPointerException();
    // 2. 把callable(mWorker)傳遞給了Sync的構造函數.
    sync = new Sync(callable);
}

Sync(Callable<V> callable) {
    // 3. 把接收過來的callable(mWorker)對象賦值給Sync類中的成員變量callable
    // 總結: Sync類中的成員變量callable就是AsyncTask中的mWorker對象.
    this.callable = callable;
}

mFuture對象中的run方法如下:

public void run() {
    // 1. 調用了innerRun方法.
    sync.innerRun();
}

void innerRun() {
    if (!compareAndSetState(READY, RUNNING))
        return;

    runner = Thread.currentThread();
    if (getState() == RUNNING) { // recheck after setting thread
        V result;
        try {
            // 2. 調用了callable(mWorker)的call方法. 獲取一個返回結果.
            result = callable.call();
        } catch (Throwable ex) {
            setException(ex);
            return;
        }
        // 4. 把結果傳遞給set方法.
        set(result);
    } else {
        releaseShared(0); // cancel
    }
}


// 在AsyncTask的構造函數中, mWorker對象初始化時, 已經覆蓋了call方法, 代碼如下
public Result call() throws Exception {
    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    // 3. 調用了用戶實現的doInBackground方法, 去執行一個耗時的任務. 運行在子線程中.
    // doInBackground接收的參數就是execute方法接收的參數.
    return doInBackground(mParams); 
}

protected void set(V v) {
    // 5. 繼續把參數傳遞給innerSet方法.
    sync.innerSet(v);
}

void innerSet(V v) {
    for (;;) {
        int s = getState();
        if (s == RAN)
            return;
        if (s == CANCELLED) {
            // aggressively release to set runner to null,
            // in case we are racing with a cancel request
            // that will try to interrupt runner
            releaseShared(0);
            return;
        }
        if (compareAndSetState(s, RAN)) {
            // 6. 把doInBackground返回的結果賦值給成員變量result
            result = v;
            releaseShared(0);
            // 7. 調用FutureTask中的done方法.
            done();
            return;
        }
    }
}

// 此方法定義在AsyncTask的構造函數中, 初始化mFuture時,已經覆蓋了done方法, 代碼如下:
@Override
protected void done() {
    Message message;
    Result result = null;

    try {
        // 8. 調用FutureTask中的get方法獲取result(doInBackground返回的結果).
        result = 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) {
        message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,
                new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));
        message.sendToTarget();
        return;
    } catch (Throwable t) {
        throw new RuntimeException("An error occured while executing "
                + "doInBackground()", t);
    }

    // 11. 創建一個消息對象.
    // msg.what = MESSAGE_POST_RESULT;
    // msg.obj = new AsyncTaskResult<Result>(AsyncTask.this, result);
    message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
            new AsyncTaskResult<Result>(AsyncTask.this, result));
    // 12. 把當前消息使用sHandler發送出去.
    message.sendToTarget();
}

public V get() throws InterruptedException, ExecutionException {
    // 9. 轉調innerGet方法.
    return sync.innerGet();
}

V innerGet() throws InterruptedException, ExecutionException {
    ...

    // 10. 把result(doInBackground的結果)返回回去. result成員變量是在innerSet方法中賦值. 詳情看第6步.
    return result;
}

private static class InternalHandler extends Handler {
    @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
    @Override
    public void handleMessage(Message msg) {
        // 把obj轉換成AsyncTaskResult類, 這個類中mTask對象就是當前的AsyncTask對象. mData對象就是doInBackground的返回結果.
        AsyncTaskResult result = (AsyncTaskResult) msg.obj;
        switch (msg.what) {
            case MESSAGE_POST_RESULT:
                // There is only one result
                // 13. 調用AsyncTask中的finish方法, 並且把doInBackground的返回結果傳遞進去.
                result.mTask.finish(result.mData[0]);
                break;
            case MESSAGE_POST_PROGRESS:
                result.mTask.onProgressUpdate(result.mData);
                break;
            case MESSAGE_POST_CANCEL:
                result.mTask.onCancelled();
                break;
        }
    }
}

private void finish(Result result) {
    if (isCancelled()) result = null;
    // 14. 把doInBackground的返回結果傳遞給用戶實現的onPostExecute方法. 運行在主線程中, 用戶可以做一些操作界面, 更新界面的操作.
    onPostExecute(result);
    mStatus = Status.FINISHED;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章