動(dòng)手實(shí)現(xiàn)AsyncTask v1.1

AsyncTask.java
AsycnTask-Api
AsyncTask是后臺(tái)執(zhí)行操作在UI線程發(fā)布結(jié)果的對(duì)象,很輕松的使用UI線程,用于耗時(shí)較短的后臺(tái)操作。

AsyncTask原理

  • AsyncTas類初始化sDefaultExecutor和sHandler變量,用于執(zhí)行后臺(tái)執(zhí)行任務(wù)和分發(fā)消息給主線程

  • AsyncTask對(duì)象創(chuàng)建時(shí)實(shí)現(xiàn)后臺(tái)執(zhí)行函數(shù)doInBackground()和發(fā)布UI結(jié)果的回調(diào)函數(shù)onPostExecute()

  • 構(gòu)造AsyncTask時(shí)

  • 構(gòu)建類型為WorkerRunnable的mWork對(duì)象,執(zhí)行doInBackground(),然后發(fā)送結(jié)束消息給sHandler

  • 構(gòu)建類型FutureTask的mFuture對(duì)象,以mWork為回調(diào)參數(shù),并重寫任務(wù)結(jié)束回調(diào)方法done(),如果上面沒(méi)有發(fā)送消息沒(méi)有成功會(huì)再次發(fā)給sHandler

  • mWork和mFuture中發(fā)送消息都調(diào)用postResult(),message的obj指向的是AsyncTaskResult對(duì)象,其包含AsyncTask對(duì)象和消息類型標(biāo)記

  • execute()啟動(dòng)時(shí)在執(zhí)行線程池處理任務(wù)之前先調(diào)用onPreExecute()

  • mFuture進(jìn)入sDefaultExecutor線程池任務(wù)隊(duì)列消費(fèi)

  • 任務(wù)執(zhí)行結(jié)束調(diào)用FutureTask的done()方法,將執(zhí)行完畢消息通過(guò)postResult()發(fā)送給sHandler

  • sHandler收到消息根據(jù)what標(biāo)記分別調(diào)用asyncTask對(duì)象的發(fā)布結(jié)果回調(diào)方法和更新UI進(jìn)度方法

注明:
AsyncTask必須在主線程中創(chuàng)建
后臺(tái)執(zhí)行回調(diào)調(diào)用publishProgress()就是發(fā)送更新進(jìn)度消息給sHandler

動(dòng)手實(shí)現(xiàn)

public abstract class AsyncTask<Params, Progress, Result> {
    private static final int MESSAGE_POST_RESULT = 1;//結(jié)束標(biāo)記
    private static final int MESSAGE_POST_PROGRESS = 2;//更新進(jìn)度標(biāo)記

    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();//cpu核心數(shù)

    //最少2個(gè)或者4個(gè)核心線程
    //cpu核心數(shù)少一個(gè)線程,以免飽和
    private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final int KEEP_ALIVE_SECONDS = 30;

    //線程創(chuàng)建工廠
    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);

        public Thread newThread(Runnable r) {
            ////參數(shù)2為線程名字
            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
        }
    };
    //最多容納128個(gè)任務(wù),再多任務(wù)就會(huì)被阻塞
    private static final BlockingQueue<Runnable> sPoolWorkQueue =
            new LinkedBlockingQueue<Runnable>(128);

    static {
        //初始化線程執(zhí)行器配置
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
                sPoolWorkQueue, sThreadFactory);
        threadPoolExecutor.allowCoreThreadTimeOut(true);
        sDefaultExecutor = threadPoolExecutor;//暫不使用哪個(gè)串行執(zhí)行的執(zhí)行器
    }

    private static volatile Executor sDefaultExecutor;
    private static InternalHandler sHnadler;

    //不適用懶加載直接使用
    static {
        sHnadler = new InternalHandler();
    }

    private final WorkerRunnable<Params, Result> mWorker;
    private final FutureTask<Result> mFuture;

    public AsyncTask() {
        //mWorker的參數(shù)在execute的時(shí)候補(bǔ)上
        mWorker = new WorkerRunnable<Params, Result>() {
            @Override
            public Result call() throws Exception {
                Result result = doInBackground(mParams);//調(diào)用后臺(tái)執(zhí)行操作
                postResult(result);//通知handler調(diào)用發(fā)布結(jié)果回調(diào)
                return result;
            }
        };
        mFuture = new FutureTask<Result>(mWorker);//暫不包裝二次檢查發(fā)送
    }

    //發(fā)送結(jié)束消息給handler
    private void postResult(Result result) {
        Message message = Message.obtain();
        message.what = MESSAGE_POST_RESULT;
        message.obj = new AsyncTaskResult(this, result);

    }

    //發(fā)送更新消息給handler
    protected void publishProgress(Progress... values) {
        Message message = Message.obtain();
        message.what = MESSAGE_POST_PROGRESS;
        message.obj = new AsyncTaskResult(this, values);
    }

    //執(zhí)行任務(wù)
    public void execute(Params... values) {
        onPreExecute();
        mWorker.mParams = values;
        sDefaultExecutor.execute(mFuture);
    }

    protected void onPreExecute() {
    }

    //后臺(tái)操作回調(diào)
    protected abstract Result doInBackground(Params... var1);

    //發(fā)布結(jié)果回調(diào)
    protected void onPostExecute(Result result) {
    }

   //進(jìn)度回調(diào)
    protected void onProgressUpdate(Progress... values) {
    }

    //主線程處理消息調(diào)用asyncTask的回調(diào)
    private static class InternalHandler extends Handler {

        public InternalHandler() {
            super(Looper.getMainLooper());
        }

        @Override
        public void handleMessage(Message msg) {
            AsyncTaskResult result = (AsyncTaskResult) msg.obj;
            switch (msg.what) {
                case MESSAGE_POST_RESULT:
                    result.mTask.onPostExecute(result.mData[0]);//發(fā)布結(jié)果回調(diào)
                    break;
                case MESSAGE_POST_PROGRESS:
                    result.mTask.onProgressUpdate(result.mData);//更新進(jìn)度回調(diào)
                    break;
            }
        }
    }

    //通過(guò)線程傳遞給doInBackground用戶定義好的參數(shù)
    private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
        Params[] mParams;
    }

    //消息攜帶類
    private static class AsyncTaskResult<Result> {
        AsyncTask mTask;//消息發(fā)送所屬AsyncTask
        Result[] mData;//結(jié)果參數(shù)

        public AsyncTaskResult(AsyncTask mTask, Result... mData) {
            this.mTask = mTask;
            this.mData = mData;
        }
    }
}

使用

asyncTask.execute("http://www.baidu.com");
...
    AsyncTask<String, Long, String> asyncTask = new AsyncTask<String, Long, String>() {
        @Override
        protected String doInBackground(String... strings) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "hello";
        }

        @Override
        protected void onPostExecute(String value) {
            super.onPostExecute(value);
            Toast.makeText(MainActivity.this, value + " over", Toast.LENGTH_SHORT).show();
        }
    };
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android開(kāi)發(fā)者:你真的會(huì)用AsyncTask嗎? 導(dǎo)讀.1 在Android應(yīng)用開(kāi)發(fā)中,我們需要時(shí)刻注意保證...
    cxm11閱讀 2,778評(píng)論 0 29
  • Android Handler機(jī)制系列文章整體內(nèi)容如下: Android Handler機(jī)制1之ThreadAnd...
    隔壁老李頭閱讀 3,435評(píng)論 1 15
  • AsyncTask異步任務(wù),用于執(zhí)行耗時(shí)任務(wù)并在UI線程中更新結(jié)果。 我們都知道,Android UI線程中不能執(zhí)...
    iyifei閱讀 3,599評(píng)論 2 9
  • 環(huán)境依賴 GrayLog 服務(wù)端需要一些環(huán)境依賴 Linux 發(fā)行版(如Debian、Ubuntu、或推薦使用的C...
    水車閱讀 724評(píng)論 0 1
  • 紀(jì)念永遠(yuǎn)的林肯公園 北京時(shí)間2017年7月21號(hào),總感覺(jué)今天會(huì)有大事發(fā)生,接到停電消息,以為今天就是沒(méi)電。因?yàn)闆](méi)電...
    舟?閱讀 349評(píng)論 6 0

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