中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android中AsyncTask的工作原理是什么

發布時間:2021-06-08 14:34:21 來源:億速云 閱讀:150 作者:小新 欄目:開發技術

這篇文章給大家分享的是有關Android中AsyncTask的工作原理是什么的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

概述

實際上,AsyncTask內部是封裝了Thread和Handler。雖然AsyncTask很方便的執行后臺任務,以及在主線程上更新UI,但是,AsyncTask并不合適進行特別耗時的后臺操作,對于特別耗時的任務,個人還是建議使用線程池。好了,話不多說了,我們先看看AsyncTask的簡單用法吧。

AsyncTask使用方法

AsyncTask是一個抽象的泛型類。簡單的介紹一下它的使用方式代碼如下:

package com.example.huangjialin.myapplication;


import android.os.AsyncTask;

import android.util.Log;


public class AsyncTaskTest extends AsyncTask<String, Object, Long>{


    @Override

    protected void onPreExecute() {

        super.onPreExecute();

        Log.i("AsyncTaskTest","---準備下載---");

    }



    @Override

    protected Long doInBackground(String... params) {



        Log.i("AsyncTaskTest","---在后臺正在下載---");

        return null;

    }


    @Override

    protected void onProgressUpdate(Object... values) {

        super.onProgressUpdate(values);

        Log.i("AsyncTaskTest","---在更新---");

    }



    @Override

    protected void onPostExecute(Long aLong) {

        super.onPostExecute(aLong);

        Log.i("AsyncTaskTest","---下載完成,將結果返回到主線程--");

    }

}

然后在activity中調用 new AsyncTaskTest().execute();就可以了...使用起來比較簡單,這里就不在講述怎么使用了。

AsyncTask的4個核心方法

1、onPreExecute():該方法在主線程中執行,在執行異步任務之前會被調用,一般用于一些準備工作。

2、doInBackground(String... params):這個方法是在線程池中執行,此方法用于執行異步任務。在這個方法中可以通過publishProgress方法來更新任務的進度,publishProgress方法會調用onProgressUpdate方法,另外,任務的結果返回給onPostExecute方法。

3、onProgressUpdate(Object... values):該方法在主線程中執行,主要用于任務進度更新的時候,該方法會被調用。

4、onPostExecute(Long aLong):在主線程中執行,在異步任務執行完畢之后,該方法會被調用,該方法的參數及為后臺的返回結果。

除了這幾個方法之外還有一些不太常用的方法,如onCancelled(),在異步任務取消的情況下,該方法會被調用。

好了,AsyncTask基本的使用就介紹到這里,下面我們進入主題,我們一起看看AsyncTask的工作原理。

AsyncTask的工作原理

先從execute走起,源碼來了

@MainThread

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

        return executeOnExecutor(sDefaultExecutor, params);

    }



    @MainThread

    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;

    }

為了方面分析,我就把英文注釋干掉了…源碼可以知道從上面的execute方法內部調用的是executeOnExecutor()方法。而sDefaultExecutor實際上是一個串行的線程池。而onPreExecute()方法在這里就會被調用了。接著看這個線程池。

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);

            }

        }

    }



public AsyncTask() {

        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);

                }

            }

        };

    }

從上面的代碼可以知道,AsyncTask的執行是排隊執行的,因為有關鍵字synchronized,而AsyncTask的Params參數就封裝成為FutureTask類,FutureTask這個類是一個并發類,在這里它充當了Runnable的作用。接著FutureTask會交給SerialExecutor的execute方法去處理,而SerialExecutor的executor方法首先就會將FutureTask添加到mTasks隊列中,如果這個時候沒有任務,就會調用scheduleNext()方法,執行下一個任務。如果有任務的話,則執行完畢后最后在調用 scheduleNext();執行下一個任務。直到所有任務被執行完畢。而AsyncTask的構造方法中有一個call()方法,而這個方法由于會被FutureTask的run方法執行。所以最終這個call方法會在線程池中執行。而doInBackground這個方法就是在這里被調用的。我們好好研究一下這個call()方法。

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;

            }

        };


private Result postResult(Result result) {

        @SuppressWarnings("unchecked")

        Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,

                new AsyncTaskResult<Result>(this, result));

        message.sendToTarget();

        return result;

    }

mTaskInvoked.set(true);表示當前任務已經執行過了。接著執行doInBackground方法,最后將結果通過postResult(result);方法進行傳遞。postResult()方法中通過sHandler來發送消息,sHandler的代碼如下:

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;

            }

        }

    }


private void finish(Result result) {

        if (isCancelled()) {

            onCancelled(result);

        } else {

            onPostExecute(result);

        }

        mStatus = Status.FINISHED;

    }

注意:AsyncTask中有兩個線程池,一個是SerialExecutor,另一個是THREAD_POOL_EXECUTOR,其中前者主要是任務進行排隊的,后者才是真正的執行任務。

而AsyncTask中還有一個方法InternalHandler,這個方法的主要作用是將執行環境從線程池切換到主線程的。

感謝各位的閱讀!關于“Android中AsyncTask的工作原理是什么”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

乐至县| 唐海县| 武义县| 吉隆县| 安龙县| 邵武市| 淳化县| 平邑县| 公主岭市| 庆城县| 信阳市| 新河县| 汨罗市| 尉犁县| 辛集市| 遂昌县| 安溪县| 灵川县| 海口市| 蒲江县| 德保县| 赣州市| 铜陵市| 乌兰浩特市| 新竹县| 昭通市| 茶陵县| 清徐县| 商南县| 金阳县| 沙洋县| 普兰店市| 英超| 丰顺县| 社会| 冷水江市| 廊坊市| 石首市| 霍山县| 华阴市| 北票市|