Android之AsyncTask源码解析

欢迎转载,请附出处:

http://blog.csdn.net/as02446418/article/details/47684415

注释都写在代码里了,直接看代码吧:

/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.os;

import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.CancellationException;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * AsyncTask能够使得操作UI线程更加容易,AsyncTask可以使得在耗时操作得到结果更新UI线程而不依靠Handler等</p>
 *
 * An asyntask能够在后台进行耗时计算操作然后把结果反馈给UI线程,整个操作是异步的,异步任务总共有三个类属性Params, Progress and Result,
 * 和4个步骤, 分别是begin,doInBackground,processProgress and end.
 *
 * AsyncTask 至少需要重写一个方法——doInBackground,最经常用的还有onPostExecute.
 * 其中三个类属性
 *    1.Params , 当任务开始时需要传给任务的参数
 *    2.Progress , 当后台计算时发布的实时进度
 *    3.Result , 后台计算的结果
 * 使用AsyncTask需要满足的条件:
 *    1.任务必须创建在UI线程中
 *    2.使用execute方法必须在UI线程中
 *    3.不要显示地调用onPreExecute,onPostExecute,doInBackground,onProgressUpdate
 *    4.任务只能exceute一次,不然会抛异常
 */
public abstract class AsyncTask<Params, Progress, Result> {
    private static final String LOG_TAG = "AsyncTask";

    private static final int CORE_POOL_SIZE = 5;
    private static final int MAXIMUM_POOL_SIZE = 128;
    private static final int KEEP_ALIVE = 1;
    //阻塞队列
    private static final BlockingQueue<Runnable> sWorkQueue =
            new LinkedBlockingQueue<Runnable>(10);

    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        //原子interger计数变量
        private final AtomicInteger mCount = new AtomicInteger(1);
        //对线程数量进行计数
        public Thread newThread(Runnable r) {
            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
        }
    };

    //定义了线程池
    private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
            MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);

    private static final int MESSAGE_POST_RESULT = 0x1;
    private static final int MESSAGE_POST_PROGRESS = 0x2;
    private static final int MESSAGE_POST_CANCEL = 0x3;
    //继承的handler类,内部自己实现的handler
    private static final InternalHandler sHandler = new InternalHandler();

    private final WorkerRunnable<Params, Result> mWorker;
    //FutureTask容器,存放结果类型
    private final FutureTask<Result> mFuture;

    private volatile Status mStatus = Status.PENDING;

    /**
     * 表明任务当前状态的枚举,且任务只能处于一种状态
     */
    public enum Status {
        /**
         * 挂起状态,还没开始任务
         */
        PENDING,
        /**
        *运行状态,表明状态正在进行
        */
        RUNNING,
        /**
         * 结束状态,表明状态已完成
         */
        FINISHED,
    }

    /**
     * 创建AsyncTask,再次声明:只能在UI线程中创建
     */
    public AsyncTask() {
        mWorker = new WorkerRunnable<Params, Result>() {
            public Result call() throws Exception {
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                return doInBackground(mParams);
            }
        };

        mFuture = new FutureTask<Result>(mWorker) {
            @Override
            protected void done() {
                Message message;
                Result result = null;

                try {
                    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);
                }

                message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
                        new AsyncTaskResult<Result>(AsyncTask.this, result));
                message.sendToTarget();
            }
        };
    }

    /**
     * 获得任务当前状态
     *
     * @return The current status.
     */
    public final Status getStatus() {
        return mStatus;
    }

    /**
     *这个就是doInBackground的抽象方法了
     *
     * @see #onPreExecute()
     * @see #onPostExecute
     * @see #publishProgress
     */
    protected abstract Result doInBackground(Params... params);

    /**
     * 在doInBackground之前执行
     *
     * @see #onPostExecute
     * @see #doInBackground
     */
    protected void onPreExecute() {
    }

    /**
     * 在doInBackground之后执行,如果任务被取消或者抛异常则返回null
     *
     * @see #onPreExecute
     * @see #doInBackground
     */
    @SuppressWarnings({"UnusedDeclaration"})
    protected void onPostExecute(Result result) {
    }

    /**
     * 在publishProgress调用后执行,其中参数的values是传给publishProgress的
     *
     * @see #publishProgress
     * @see #doInBackground
     */
    @SuppressWarnings({"UnusedDeclaration"})
    protected void onProgressUpdate(Progress... values) {
    }

    /**
     * 在cancel()被调用后执行的方法
     *
     * @see #cancel(boolean)
     * @see #isCancelled()
     */
    protected void onCancelled() {
    }

    /**
     * 如果在正常结束之前取消任务了则返回true,否则为false
     */
    public final boolean isCancelled() {
        return mFuture.isCancelled();
    }

    /**
     * 试图取消执行的任务,途中可能会失败如果任务已经完成了,或者已经被取消了,或者其他原因,
     * 如果这个方法在任务启动之前调用则任务不会启动,如果在启动之后调用,
     * 传入的参数mayInterruptIfRunning决定了是不是要在任务运行的时候终止任务
     * @see #isCancelled()
     * @see #onCancelled()
     */
    public final boolean cancel(boolean mayInterruptIfRunning) {
        return mFuture.cancel(mayInterruptIfRunning);
    }

    /**
     * 等待直到结果完成的时候则返回结果
     *
     * @return The computed result.
     *
     * @throws CancellationException If the computation was cancelled.
     * @throws ExecutionException If the computation threw an exception.
     * @throws InterruptedException If the current thread was interrupted
     *         while waiting.
     */
    public final Result get() throws InterruptedException, ExecutionException {
        return mFuture.get();
    }

    /**
     * 等到timeout结束时就检查结果,不管任务有没有完成,通常放到耗时任务时
     *
     * @param timeout Time to wait before cancelling the operation.
     * @param unit The time unit for the timeout.
     *
     * @return The computed result.
     *
     * @throws CancellationException If the computation was cancelled.
     * @throws ExecutionException If the computation threw an exception.
     * @throws InterruptedException If the current thread was interrupted
     *         while waiting.
     * @throws TimeoutException If the wait timed out.
     */
    public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
            ExecutionException, TimeoutException {
        return mFuture.get(timeout, unit);
    }

    /**
     * 返回AsyncTask<Params, Progress, Result>对象,需要在UI线程中执行
     *
     *
     * @param params The parameters of the task.
     *
     * @return This instance of AsyncTask.
     *
     * @throws IllegalStateException If {@link #getStatus()} returns either
     *         {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}.
     */
    public final AsyncTask<Params, Progress, Result> execute(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;
        sExecutor.execute(mFuture);

        return this;
    }

    /**
     * 这个方法会被doInBackground调用并表示当前已完成的状态
     *
     * @see #onProgressUpdate
     * @see #doInBackground
     */
    protected final void publishProgress(Progress... values) {
        sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
                new AsyncTaskResult<Progress>(this, values)).sendToTarget();
    }

    /**
    * 任务任务时候内部自动调用此方法
    */
    private void finish(Result result) {
        if (isCancelled()) result = null;
        onPostExecute(result);
        mStatus = Status.FINISHED;
    }
    /**
    * 这个是最重要的内部实现的handler了,根据不同的msg进行分发不同操作
    */
    private static class InternalHandler extends Handler {
        @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;
                case MESSAGE_POST_CANCEL:
                    result.mTask.onCancelled();
                    break;
            }
        }
    }

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

    @SuppressWarnings({"RawUseOfParameterizedType"})
    private static class AsyncTaskResult<Data> {
        final AsyncTask mTask;
        final Data[] mData;

        AsyncTaskResult(AsyncTask task, Data... data) {
            mTask = task;
            mData = data;
        }
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-07 14:11:45

Android之AsyncTask源码解析的相关文章

Android:AsyncTask源码解析

简单实例 这里直接拿以前写过的一个小Demo,根据这个Demo来分析源码. public class MainActivity extends ActionBarActivity { ... Private MyAsyncTask asyncTask; protected void onCreate(Bundle savedInstanceState) { ... asyncTask = new MyAsyncTask(); // 点击button进行异步任务 button.setOnClick

Android MIFARE NFCA源码解析

Android MIFARE NFCA源码解析TagTechnology定义了所有标签的共有接口类BasicTagTechnology 实现了TagTechnology的一些接口 再有具体的标签协议继承BasicTagTechnologyNFC-A 遵循ISO 14443-3A协议. 关键字ATQA Answer To Request acc. to ISO/IEC 14443-4ATS Answer To Select acc. to ISO/IEC 14443-4DIF Dual Inter

Android 开源项目源码解析(第二期)

Android 开源项目源码解析(第二期) 阅读目录 android-Ultra-Pull-To-Refresh 源码解析 DynamicLoadApk 源码解析 NineOldAnimations 源码解析 SlidingMenu 源码解析 Cling 源码解析 BaseAdapterHelper 源码分析 Side Menu.Android 源码解析 DiscreteSeekBar 源码解析 CalendarListView 源码解析 PagerSlidingTabStrip 源码解析 公共

Android AsyncTask 源码解析

1. 官方介绍 public abstract class AsyncTask extends Object  java.lang.Object    ? android.os.AsyncTask<Params, Progress, Result> AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish resul

Android异步消息处理机制(4)AsyncTask源码解析

上一章我们学习了抽象类AsyncTask的基本使用(地址:http://blog.csdn.net/wangyongge85/article/details/47988569),下面我将以问答的方法分析AsyncTask源码内容,源码版本为:API22. 1. 为什么必须在UI线程实例化我们的AsyncTask,并且必须在主线程中调用execute(Params... params)? 在分析为什么在UI线程调用之前,我们先看一下实例化AsyncTask并调用execute(Params...

Android -- AsyncTask源码解析

1,前段时间换工作的时候,关于AsyncTask源码这个点基本上大一点的公司都会问,所以今天就和大家一起来总结总结.本来早就想写这篇文章的,当时写<Android -- 从源码解析Handle+Looper+MessageQueue机制>的时候就是想为这篇文章做铺垫的,因为AsyncTask说里面还是使用的handle,所以先就写了handle这一篇.记得15年底去美团面试的时候,面试官就问我既然存在handle为什么google还要出AsyncTask(毕竟底层还是用的handle+Exec

Android源码探究之AsyncTask 源码解析

AsyncTask源码使用 Api23版本,后面介绍和以前版本改动不同之处. 先看使用: /** * 下面四个方法中除了doInBackground方法在子线程,其他方法都在主线程执行 * String 表示传进来的参数, * Void 表示子线程执行过程中对主线程进行反馈所传的数据类型 * Integer 子线程执行的结果 */ private class MyAsyncTask extends AsyncTask<String,Void,Integer>{ @Override protec

Android异步处理框架AsyncTask源码解析

一.概述 在Android开发中,我们进行异步处理一般会采用两种方式: 1.Thread +Handler 通常我们在Thread里面发送消息,然后在Handler的handleMessage方法里面去处理对应的任务,因为Android是不允许UI线程去更新UI的,这个时候我们可以采取这种方式 2.AsyncTask AsyncTask是Android为我们封装的一个轻量级的异步处理框架,其实底层也是用了类似Thread+Handler的方式.对外提供了一些方法,我们实现这些方法就可以很方便的进

Android的ViewDragHelper源码解析

其实我想看的是DrawerLayout, 但发现DrawerLayout里面是使用了ViewDragHelper去实现. 谷歌比较早就放出这个类了,但ViewDragHelper是开发中很少用到一个类.顾名思义这是一个和拖曳触摸有关的类. 本着追根溯源的想法, 加上ViewDragHelper的源码也不算多,就决定将ViewDragHelper的源码看一遍.对实现原理了解下. 代码一千多行,看完还是需要点时间的. 因此不会逐一讲完, 当然下面也会放出该类源码的解析,注释中也有一些个人理解的点写在