Android AsyncTask工作機制源碼剖析

前言

上一篇文章我們一起分析了Android消息機制的實現(xiàn)原理,通過分析我們知道,Android系統(tǒng)規(guī)定不能在主線程(UI線程)中執(zhí)行耗時操作,這就需要我們在子線程中處理耗時操作,然后在執(zhí)行完耗時操作后我們可以通過Handler發(fā)送一個消息給主線程通知其進(jìn)行刷新UI等操作。如果對這一塊知識點還不清楚,請參考前面的文章Android Handler-帶你從源碼理解消息機制。而本篇文章要說到的是AsyncTask這個類,這個類就是專門用來處理異步任務(wù)的,它完成了對Thread和Handler的封裝,我們只需在它的doInBackground方法中執(zhí)行我們的耗時操作,在執(zhí)行完耗時操作后,它的內(nèi)部會完成調(diào)用Handler向主線程發(fā)送完成消息的邏輯,而不需要我們自行去處理。接下來就讓我們一起走進(jìn)它的源碼,來分析一下它內(nèi)部的實現(xiàn)原理(文章參考sdk29源碼進(jìn)行分析)。

AsyncTask

1.基本用法:

在AsyncTask的源碼注釋中,列舉了AsyncTask的一個最基本的使用方式,如下:

private class DownloadFilesTask extends AsyncTask(URL, Integer, Long) {
    protected Long doInBackground(URL... urls) {
        int count = urls.length;
        long totalSize = 0;
        for (int i = 0; i < count; i++) {
            totalSize += Downloader.downloadFile(urls[i]);
            publishProgress((int) ((i / (float) count) * 100));
            // Escape early if cancel() is called
            if (isCancelled()) break;
         }
         return totalSize;
     }

    protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }
 
     protected void onPostExecute(Long result) {
        showDialog("Downloaded " + result + " bytes");
    }
}

AsyncTask是一個抽象的范型類,內(nèi)部存在一個抽象方法doInBackground,我們需要創(chuàng)建一個類繼承它,并實現(xiàn)它的doInBackground方法,在這個方法的內(nèi)部我們來實現(xiàn)具體的耗時操作的邏輯。它的三個范型參數(shù)分別為Params, Progress, Result,其中Params為執(zhí)行任務(wù)時發(fā)送給任務(wù)的參數(shù)類型,doInBackground方法中的參數(shù)類型就是和這個Params類型一致的,上例中指定成了URL類型;Progress為任務(wù)執(zhí)行的進(jìn)度類型,通常指定為Integer類型;最后一個Result為任務(wù)返回結(jié)果的類型。當(dāng)我們要通過上面的DownloadFilesTask執(zhí)行下載文件的操作時,我們只需創(chuàng)建DownloadFilesTask實例并調(diào)用它的execute方法即可,在execute方法中我們需要傳入任務(wù)執(zhí)行所需的參數(shù),即Params范型所對應(yīng)的類型參數(shù)。

2.執(zhí)行步驟:

一個AsyncTask任務(wù)從開始執(zhí)行到結(jié)束,一共會經(jīng)歷四個步驟,它們分別是:

2.1.onPreExecute:

在任務(wù)開始執(zhí)行之前在主線程中被調(diào)用,通常用來進(jìn)行一些準(zhǔn)備工作,比如顯示一個進(jìn)度條。

2.2.doInBackground:

在執(zhí)行完onPreExecute方法之后,該方法就會被調(diào)用。此方法用于執(zhí)行耗時操作,異步任務(wù)的參數(shù)傳遞到此方法中,此方法會返回一個計算結(jié)果并將其傳遞到最后一步onPostExecute方法中。在操作執(zhí)行的過程中,還可以調(diào)用publishProgress方法將操作執(zhí)行的進(jìn)度傳遞到onProgressUpdate方法中。

2.3.onProgressUpdate:

此方法用于在耗時操作執(zhí)行的過程中,在用戶界面以任意的形式展示當(dāng)前操作執(zhí)行的進(jìn)度,該方法是在主線程中被調(diào)用的。

2.4.onPostExecute:

在耗時操作執(zhí)行完畢時,該方法會在主線程中被調(diào)用,并且耗時操作返回的結(jié)果將被傳入到此方法的參數(shù)中。

在前面的AsyncTask使用示例中,我們已經(jīng)看到了其中的三個步驟方法,通常情況下,除了doInBackground方法是必須被重寫的,其他三個方法我們可以根據(jù)自身的需求來選擇性的去使用。

3.注意事項:

在使用AsyncTask類的時候,這里有一些注意事項還是要知道的:

    1. AsyncTask類必須在主線程中完成加載。
    1. AsyncTask實例必須在主線程中創(chuàng)建。
    1. AsyncTask的execute方法必須在主線程中調(diào)用。
    1. 不要手動調(diào)用它的onPreExecute、onPostExecute、doInBackground、onProgressUpdate方法。
    1. 一個AsyncTask任務(wù)只能被執(zhí)行一次,否則會在第二次調(diào)用execute方法時拋出異常。

4.走進(jìn)源碼:

4.1構(gòu)造方法:

AsyncTask的構(gòu)造方法一共有三個,我們先來看下這三個方法的源代碼:

public AsyncTask() { this((Looper) null); }

public AsyncTask(@Nullable Handler handler) { this(handler != null ? handler.getLooper() : null); }

public AsyncTask(@Nullable Looper callbackLooper) {
    mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
            ? getMainHandler() : new Handler(callbackLooper);
    mWorker = new WorkerRunnable<Params, Result>() {
        public Result call() throws Exception {
            mTaskInvoked.set(true);
            Result result = null;
            try {
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                //noinspection unchecked
                result = doInBackground(mParams);
                Binder.flushPendingCommands();
            } catch (Throwable tr) {
                mCancelled.set(true);
                throw tr;
            } finally {
                postResult(result);
            }
            return result;
        }
    };
    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 occurred while executing doInBackground()",
                            e.getCause());
            } catch (CancellationException e) {
                postResultIfNotInvoked(null);
            }
        }
    };
}

通常情況下我們調(diào)用它的無參構(gòu)造來創(chuàng)建一個AsyncTask,而在這個無參構(gòu)造的內(nèi)部調(diào)用的是它的帶有一個Looper 類型參數(shù)的構(gòu)造,在這個構(gòu)造方法中會初始化三個變量,分別為mHandler、mWorker、mFuture,而這三個實例對應(yīng)的類型分別為InternalHandler、WorkerRunnable、FutureTask,這三個變量可以說是AsyncTask完成異步任務(wù)過程中的重要角色,把這三個變量的意義弄懂基本上后面的任務(wù)執(zhí)行流程就能很輕松的理解了。

4.2.InternalHandler:

首先說一下這個InternalHandler,這個類是AsyncTask的一個靜態(tài)內(nèi)部類,繼承自Handler,只不過它的內(nèi)部重寫了handleMessage方法,源碼如下:

private static class InternalHandler extends Handler {
    public InternalHandler(Looper looper) {
        super(looper);
    }

    @Override
    public void handleMessage(Message msg) {
        AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
        switch (msg.what) {
            case MESSAGE_POST_RESULT:
                result.mTask.finish(result.mData[0]);
                break;
            case MESSAGE_POST_PROGRESS:
                result.mTask.onProgressUpdate(result.mData);
                break;
        }
    }
}

在它的handleMessage方法中,只會處理兩種類型的消息,一種是MESSAGE_POST_RESULT類型的消息,也就是當(dāng)任務(wù)執(zhí)行完成時發(fā)送出的消息;而另一種是MESSAGE_POST_PROGRESS類型的消息,也就是在任務(wù)執(zhí)行過程中更新進(jìn)度的消息。在這個方法中可以看到一個AsyncTaskResult類,這個類也是AsyncTask的一個靜態(tài)內(nèi)部類,它的源碼如下:

private static class AsyncTaskResult<Data> {
    final AsyncTask mTask;
    final Data[] mData;
    AsyncTaskResult(AsyncTask task, Data... data) {
        mTask = task;
        mData = data;
    }
}

這個類可以看成是一個數(shù)據(jù)承載類,在AsyncTask的工作機制中它會被賦值成InternalHandler發(fā)送的消息中的obj變量,它會承載兩種類型的數(shù)據(jù),一種就是任務(wù)執(zhí)行過程中的進(jìn)度數(shù)據(jù),一種就是任務(wù)執(zhí)行完成的結(jié)果數(shù)據(jù)。在AsyncTaskResult類的內(nèi)部擁有兩個成員變量mTask和mData,其中mTask為AsyncTask類型,在所有創(chuàng)建AsyncTaskResult實例的地方都會將其指向當(dāng)前的AsyncTask;另一個mData是一個數(shù)組,當(dāng)AsyncTaskResult承載的是進(jìn)度數(shù)據(jù)時,mData的類型會與AsyncTask類的Progress泛型一致;而當(dāng)AsyncTaskResult承載的是結(jié)果數(shù)據(jù)時,mData的類型會與AsyncTask類的Result泛型一致?,F(xiàn)在回到InternalHandler的handleMessage方法,當(dāng)接收的消息為MESSAGE_POST_RESULT類型時,會調(diào)用到AsyncTask的finish方法,源碼如下:

private void finish(Result result) {
    if (isCancelled()) { // isCancelled方法的內(nèi)部會判斷當(dāng)前的任務(wù)是否已經(jīng)取消掉
        onCancelled(result);
    } else {
        onPostExecute(result);
    }
    mStatus = Status.FINISHED;
}

在finish方法的內(nèi)部會進(jìn)行判斷,如果當(dāng)前的任務(wù)已經(jīng)被cancel掉了,那么就調(diào)用onCancelled方法(內(nèi)部再調(diào)用onCancelled的無參重載方法,是一個空方法,可以根據(jù)需要來實現(xiàn)具體的邏輯);如果當(dāng)前任務(wù)沒有被cancel掉,就會調(diào)用前面我們說過的onPostExecute方法,這個方法本身也是一個空方法,我們可以重寫這個方法并在方法內(nèi)部對任務(wù)執(zhí)行的結(jié)果進(jìn)行相應(yīng)的處理,最后在方法的結(jié)尾處會將mStatus變量的值置為Status.FINISHED,此時代表任務(wù)執(zhí)行完成;再次回到InternalHandler的handleMessage方法中,當(dāng)接收的消息為MESSAGE_POST_PROGRESS類型時,會調(diào)用AsyncTask的onProgressUpdate方法,這個方法前面也是說到過,也是一個空方法,我們可以重寫這個方法在里面進(jìn)行一些更新任務(wù)執(zhí)行進(jìn)度的提示操作。

4.3.WorkerRunnable:

這個WorkerRunnable是AsyncTask的一個靜態(tài)內(nèi)部類,它實現(xiàn)了Callable接口,并且它的范型和AsyncTask的兩個范型相對應(yīng),源代碼如下:

private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
    Params[] mParams;
}

在它的內(nèi)部只有一個mParams數(shù)組變量,類型與Params范型一致,現(xiàn)在再來看一下在構(gòu)造方法中mWorker變量的初始化方式:

mWorker = new WorkerRunnable<Params, Result>() {
    public Result call() throws Exception {
        /**
         * 這個mTaskInvoked是一個AtomicBoolean類型的變量;
         * 一旦當(dāng)前AsyncTask任務(wù)中的mWorker的call被調(diào)用,這個mTaskInvoked變量中的value值就會被置為1;
         * 在AtomicBoolean類的內(nèi)部存在一個value變量,值為1時代表true,值為0時代表false;
         */ 
        mTaskInvoked.set(true); 
        Result result = null;
        try {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            result = doInBackground(mParams); 
            Binder.flushPendingCommands();
        } catch (Throwable tr) {
            mCancelled.set(true);
            throw tr;
        } finally {
            postResult(result);
        }
        return result;
    }
};

因為WorkerRunnable是一個抽象類,所以只能通過匿名類的方式創(chuàng)建它的實例,其內(nèi)部實現(xiàn)的call方法是Callable接口中的。在這個call方法的內(nèi)部我們看到了一個非常關(guān)鍵的方法,即前面說到的用來執(zhí)行耗時任務(wù)的doInBackground方法,通過doInBackground方法執(zhí)行具體的耗時任務(wù)并返回一個任務(wù)結(jié)果,在call方法的最后會調(diào)用postResult方法將返回的任務(wù)結(jié)果發(fā)送給mHandler處理,方法的源碼如下:

private Result postResult(Result result) {
    @SuppressWarnings("unchecked")
    Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, 
          new AsyncTaskResult<Result>(this, result));
    message.sendToTarget();
    return result;
}

在方法的內(nèi)部就是通過mHandler發(fā)送處一條MESSAGE_POST_RESULT類型的消息,消息的obj變量為一個范型被指定Result類型的AsyncTaskResult對象,最終這個消息會被mHandler處理,至于消息處理的邏輯前面剛剛講過這里不再贅述。通過分析mWorker的call方法,我們可以知道在AsyncTask中,mWorker扮演著任務(wù)的執(zhí)行者角色,一個AsyncTask任務(wù)是在mWorker的call方法中被真正執(zhí)行的。

4.4.FutureTask:

這個類并不是AsyncTask的內(nèi)部類,也并不是單單只會出現(xiàn)在AsyncTask的使用場景中,它可以理解成一個將要被執(zhí)行的任務(wù),在執(zhí)行之前存在被取消掉的可能,這個類間接的實現(xiàn)了Runnable接口。在前面的AsyncTask的構(gòu)造方法中,它的實例化方式如下:

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 occurred while executing doInBackground()", e.getCause());
        } catch (CancellationException e) {
            postResultIfNotInvoked(null);
        }
    }
};

這里調(diào)用它的一個參數(shù)的構(gòu)造方法,將剛剛的mWorker變量傳入FutureTask中,并且重寫了它的done方法。在后面我們要說到的AsyncTask的execute方法中,這個mFuture變量最終會被交給一個線程池去處理,當(dāng)線程池調(diào)用execute方法執(zhí)行這個FutureTask時,這個FutureTask的run方法將會被調(diào)用(FutureTask實現(xiàn)了Runnable接口,這里需要對線程以及線程池的內(nèi)部原理有一定的了解),而在FutureTask的run方法中,在構(gòu)造方法中傳入的mWorker變量的call方法又將會得到調(diào)用(WorkerRunnable實現(xiàn)了Callable接口),從而使得AsyncTask的任務(wù)得到真正的執(zhí)行。關(guān)于FutureTask的run方法的源碼如下:

public void run() {
    ........
    try {
        Callable<V> c = callable; // 這個callable就是構(gòu)造方法中傳入的Callable對象,即mWorker
        if (c != null && state == NEW) {
            V result;
            boolean ran;
            try {
                result = c.call(); // 在這里Callable對象的call方法將會被調(diào)用
                ran = true;
            } catch (Throwable ex) {
                ........
            }
            if (ran)
                set(result); 
        }
    } finally {
        ........
    }
}

而在實例化mFuture對象時重寫的這個done方法,在FutureTask類中的finishCompletion方法中會被調(diào)用,而finishCompletion方法存在三處被調(diào)用的地方,其中一處就在剛剛說到的run方法的結(jié)尾處調(diào)用的set方法內(nèi)部,關(guān)于這個done方法內(nèi)部調(diào)用的postResultIfNotInvoked方法,源碼如下:

private void postResultIfNotInvoked(Result result) {
    final boolean wasTaskInvoked = mTaskInvoked.get();
    if (!wasTaskInvoked) {
        postResult(result);
    }
}

在前面說到的mWorker的call方法中,mTaskInvoked變量會調(diào)用set方法傳入true,此時如果我們調(diào)用mTaskInvoked的get方法獲取到的返回值就為true。在AsyncTask中這個mTaskInvoked變量只有這一處調(diào)用set方法的地方,因此可以得出一個結(jié)論,一旦mWorker的call被調(diào)用了,那么在postResultIfNotInvoked方法中就不會執(zhí)行postResult方法。正常情況下,只要調(diào)用了AsyncTask的execute方法開始執(zhí)行任務(wù),mWorker的call方法就會被正常調(diào)用,postResult方法也會在call方法的結(jié)尾處調(diào)用,而在done方法的內(nèi)部就不會再次執(zhí)行postResult方法;而如果當(dāng)前的任務(wù)還未被執(zhí)行,此時調(diào)用了AsyncTask的cancel方法取消任務(wù),這時mWorker的call方法還未被調(diào)用,也就是說這時mTaskInvoked通過get方法返回的值為默認(rèn)值false,那么此時如果mFuture的done方法被調(diào)用,postResult方法就會在其內(nèi)部被調(diào)用。而AsyncTask的cancel方法內(nèi)部其實就是調(diào)用mFuture的cancel方法,最終就會導(dǎo)致mFuture的done方法被調(diào)用,因此當(dāng)一個AsyncTask任務(wù)如果在執(zhí)行之前被取消掉,那么它的postResult方法會在mFuture的done方法中被調(diào)用。

4.5.execute方法:

在了解了AsyncTask的構(gòu)造方法的邏輯之后,我們來看一下它的開啟任務(wù)執(zhí)行的execute方法:

@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
    return executeOnExecutor(sDefaultExecutor, params);
}

方法的內(nèi)部繼續(xù)調(diào)用executeOnExecutor方法,executeOnExecutor方法接收兩個參數(shù),第一個參數(shù)是一個實現(xiàn)了Executor接口類型的參數(shù),第二個參數(shù)為execute方法中傳入的最終執(zhí)行任務(wù)所需的參數(shù)。在execute方法中傳給executeOnExecutor方法的第一個參數(shù)為sDefaultExecutor變量,sDefaultExecutor是AsyncTask類的一個靜態(tài)變量,這個變量的類型為SerialExecutor類型,而SerialExecutor也是AsyncTask的一個靜態(tài)內(nèi)部類。關(guān)于這個SerialExecutor類后面再做詳細(xì)分析,我們先來看一下executeOnExecutor方法的源碼:

@MainThread
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) {
1    if (mStatus != Status.PENDING) {
2        switch (mStatus) {
3            case RUNNING:
4                throw new IllegalStateException("Cannot execute task:"
5                            + " the task is already running.");
6            case FINISHED:
7                throw new IllegalStateException("Cannot execute task:"
8                            + " the task has already been executed "
9                            + "(a task can be executed only once)");
10        }
11    }
12    mStatus = Status.RUNNING;
13    onPreExecute();
14    mWorker.mParams = params;
15    exec.execute(mFuture);
16    return this;
}

首先,對mStatus 變量的值進(jìn)行判斷,這個mStatus 是一個枚舉類型的變量,它的值有三種可能:

1.Status.PENDING: 任務(wù)尚未執(zhí)行。
2.Status.RUNNING: 任務(wù)正在執(zhí)行。
3.Status.FINISHED: 任務(wù)已經(jīng)執(zhí)行完成。

默認(rèn)情況下mStatus的值為Status.PENDING,在AsyncTask中mStatus存在兩處賦值的地方,一處是前面說到的finish方法中會將其置為Status.FINISHED,另一處就是當(dāng)前的executeOnExecutor方法的第12行會將其置為Status.RUNNING。
現(xiàn)在回到executeOnExecutor方法,當(dāng)mStatus的值不等于Status.PENDING時方法就會拋出異常,這也就驗證了AsyncTask的execute方法確實只能調(diào)用一次,當(dāng)mStatus的值為Status.PENDING時,說明此時任務(wù)還未被執(zhí)行,那么就向下執(zhí)行調(diào)用前面說到的onPreExecute方法(注意此時異步任務(wù)還未真正開始執(zhí)行),這個方法本身是一個空方法,如果我們需要在任務(wù)正式開始執(zhí)行前做一些什么準(zhǔn)備操作的話可以重寫該方法來編寫適當(dāng)?shù)倪壿?;接著將傳給任務(wù)的參數(shù)賦值給mWorker的mParams變量,這個mParams最終會在mWorker的call方法中傳給AsyncTask的doInBackground方法;最后在第15行會執(zhí)行Executor的execute方法來執(zhí)行當(dāng)前的mFuture任務(wù)了,接下來就要揭曉AsyncTask中的兩個最關(guān)鍵的角色了。

4.6.線程池SerialExecutor:

前面我們已經(jīng)提到過,在AsyncTask的execute方法中傳給executeOnExecutor方法的第一個參數(shù)為sDefaultExecutor變量,而sDefaultExecutor是一個SerialExecutor類型的靜態(tài)變量,那么我們來看一下SerialExecutor類的源代碼:

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(); // 內(nèi)部會調(diào)用mWorker的call方法去執(zhí)行doInBackground方法
                } finally {
                    scheduleNext();
                }
            }
        });
        if (mActive == null) {
            scheduleNext();
        }
    }

    protected synchronized void scheduleNext() {
        if ((mActive = mTasks.poll()) != null) {
            THREAD_POOL_EXECUTOR.execute(mActive);
        }
    }
}

在SerialExecutor的內(nèi)部,擁有兩個成員變量mTasks和mActive,其中mTasks為范型為Runnable的隊列,用于存儲Runnable對象,在AsyncTask類中就是FutureTask對象。在execute方法中,首先調(diào)用ArrayDeque的offer方法將傳入的FutureTask對象添加到mTasks的結(jié)尾,然后判斷mActive變量是否為空,如果為空就調(diào)用scheduleNext方法,在scheduleNext方法中首先會將mActive指向mTasks中的第一個元素(ArrayDeque的poll方法返回隊列中的第一個元素),如果mActive不為空,就會去調(diào)用THREAD_POOL_EXECUTOR線程池的execute方法執(zhí)行當(dāng)前的mActive,而在線程池的execute方法中,mActive的run方法最終就會被調(diào)用(這一點前面也提到過,需要對線程池和線程的執(zhí)行原理有一定的了解)?,F(xiàn)在再來看下剛剛在調(diào)用mTasks的offer方法添加FutureTask對象時重寫了FutureTask的run方法,在run方法中先是執(zhí)行FutureTask自身的run方法,然后會接著調(diào)用scheduleNext方法,如果mTasks中還有FutureTask對象,就繼續(xù)執(zhí)行下一個FutureTask,由此可知AsyncTask中的任務(wù)其實是串行執(zhí)行的。

4.7.THREAD_POOL_EXECUTOR:

到這里其實AsyncTask任務(wù)的執(zhí)行流程就差不多分析完了,只不過還有一個重要角色沒介紹,那就是執(zhí)行FutureTask的線程池THREAD_POOL_EXECUTOR,它是AsyncTask的一個靜態(tài)變量,就是一個正常的ThreadPoolExecutor類型的線程池,它的核心線程數(shù)為1,最大線程數(shù)為20,這也就意味著當(dāng)使用默認(rèn)的THREAD_POOL_EXECUTOR線程池時AsyncTask允許同時執(zhí)行的任務(wù)最多有20個。如果覺著默認(rèn)的線程池不滿足你的需要,我們也可以通過調(diào)用AsyncTask的setDefaultExecutor方法為當(dāng)前的AsyncTask設(shè)置自定義的線程池來執(zhí)行任務(wù)。

總結(jié)

AsyncTask的主要知識點以及任務(wù)的執(zhí)行機制基本上就分析完了,在它的內(nèi)部有幾個重要的角色如下:

1.AsyncTask的內(nèi)部存在兩個線程池,一個是SerialExecutor類型的sDefaultExecutor,它用來存儲將要被執(zhí)行的FutureTask任務(wù),使任務(wù)按順序串行執(zhí)行;另一個THREAD_POOL_EXECUTOR為ThreadPoolExecutor類型,它用于執(zhí)行FutureTask任務(wù)。
2.InternalHandler類型的mHandler對象負(fù)責(zé)處理任務(wù)執(zhí)行過程中的消息傳遞。
3.FutureTask類型的mFuture對象,代表一個將要被THREAD_POOL_EXECUTOR執(zhí)行的任務(wù)。
4.WorkerRunnable類型的mWorker對象,是任務(wù)的真正執(zhí)行者,它被mFuture對象持有。

當(dāng)調(diào)用構(gòu)造方法創(chuàng)建一個AsyncTask實例時,會在構(gòu)造方法中創(chuàng)建三個變量,分別為傳遞消息的mHandler、任務(wù)的真正執(zhí)行者mWorker以及將要被執(zhí)行的任務(wù)mFuture,其中mWorker會被傳入到mFuture的內(nèi)部,當(dāng)mFuture的run方法被調(diào)用時,mWorker的call方法就會被調(diào)用,最終doInBackground方法就會被執(zhí)行,耗時任務(wù)就得以執(zhí)行;當(dāng)創(chuàng)建完AsyncTask實例后,調(diào)用它的execute方法將mFuture添加到sDefaultExecutor中,最終再交給THREAD_POOL_EXECUTOR的execute方法去處理,這時mFuture的run方法就會被調(diào)用。至此,整個AsyncTask的工作機制就已經(jīng)分析完了!最后,如果文章對您有幫助,還希望點贊支持下!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容