Android中的多线程-AsyncTask源码分析

来源:互联网 发布:非织造材料与工程 知乎 编辑:程序博客网 时间:2024/05/16 05:19
/* * */public abstract class AsyncTask<Params, Progress, Result> {//Params是传入的参数,Progress用于显示进度 ,Result则为doinBackground传递给Post的参数    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 = 10;//线程池所使用的缓冲队列    private static final BlockingQueue<Runnable> sWorkQueue =            new LinkedBlockingQueue<Runnable>(10);    private static final ThreadFactory sThreadFactory = new ThreadFactory() {        private final AtomicInteger mCount = new AtomicInteger(1);        public Thread newThread(Runnable r) {            return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());        }    };//TimeUnit.SECONDS线程池维护线程所允许的空闲时间的单位    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;//因为整个AsyncTask是在UI线程创建的,所以sHandler对应到UI线程Message Queue,所以可以更新UI    private static final InternalHandler sHandler = new InternalHandler();    private final WorkerRunnable<Params, Result> mWorker;    private final FutureTask<Result> mFuture;    private volatile Status mStatus = Status.PENDING;    /**     * Indicates the current status of the task. Each status will be set only once     * during the lifetime of a task.     */    public enum Status {        /**         * Indicates that the task has not been executed yet. * 还没有被execute         */        PENDING,        /** * 运行中         * Indicates that the task is running.         */        RUNNING,        /** * onPostExecute 执行完毕,这些线程其实是没法终止的         * Indicates that {@link AsyncTask#onPostExecute} has finished.         */        FINISHED,    }    /** * 异步的任务,必须是在UI线程创建     * Creates a new asynchronous task. This constructor must be invoked on the UI thread.     */    public AsyncTask() {//参数和结果队,是一个runnable用来执行后台任务,调用doInBackground//WorkerRunnable是一个继承自Callable<Result>带有回调功能的类        mWorker = new WorkerRunnable<Params, Result>() {            public Result call() throws Exception {                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);                return doInBackground(mParams);            }        };//sExecutor.execute(mFuture)会先执行带有回调的mWorker,执行完毕之后会执行done()方法        mFuture = new FutureTask<Result>(mWorker) {            @Override            protected void done() {                Message message;                Result result = null;                try {                    result = get();                } catch (InterruptedException e) {//线程被Interrupt了                    android.util.Log.w(LOG_TAG, e);                } catch (ExecutionException e) {//执行异常                    throw new RuntimeException("An error occured while executing doInBackground()",                            e.getCause());                } catch (CancellationException e) {//执行cancel?通过sendToTarget                    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);                }//通过sendMessage和Handler配合完成doInBackground和onPostExecute的关联                message = sHandler.obtainMessage(MESSAGE_POST_RESULT,                        new AsyncTaskResult<Result>(AsyncTask.this, result));                message.sendToTarget();            }        };    }    /**     * Returns the current status of this task.     *     * @return The current status.     */    public final Status getStatus() {        return mStatus;    }    /**     * Override this method to perform a computation on a background thread. The     * specified parameters are the parameters passed to {@link #execute}     * by the caller of this task.     *     * This method can call {@link #publishProgress} to publish updates     * on the UI thread.     *     * @param params The parameters of the task.     *     * @return A result, defined by the subclass of this task.     *     * @see #onPreExecute()     * @see #onPostExecute     * @see #publishProgress     */    protected abstract Result doInBackground(Params... params);    /**     * Runs on the UI thread before {@link #doInBackground}.     *     * @see #onPostExecute     * @see #doInBackground     */    protected void onPreExecute() {    }    /**     * Runs on the UI thread after {@link #doInBackground}. The     * specified result is the value returned by {@link #doInBackground}     * or null if the task was cancelled or an exception occured.     *     * @param result The result of the operation computed by {@link #doInBackground}.     *     * @see #onPreExecute     * @see #doInBackground     */    @SuppressWarnings({"UnusedDeclaration"})    protected void onPostExecute(Result result) {    }    /**     * Runs on the UI thread after {@link #publishProgress} is invoked.     * The specified values are the values passed to {@link #publishProgress}.     *     * @param values The values indicating progress.     *     * @see #publishProgress     * @see #doInBackground     */    @SuppressWarnings({"UnusedDeclaration"})    protected void onProgressUpdate(Progress... values) {    }    /**     * Runs on the UI thread after {@link #cancel(boolean)} is invoked.     *     * @see #cancel(boolean)     * @see #isCancelled()     */    protected void onCancelled() {    }    /**     * Returns <tt>true</tt> if this task was cancelled before it completed     * normally. * 判断是否被cancel了     *     * @return <tt>true</tt> if task was cancelled before it completed     *     * @see #cancel(boolean)     */    public final boolean isCancelled() {        return mFuture.isCancelled();    }    /**     * Attempts to cancel execution of this task.  This attempt will     * fail if the task has already completed, already been cancelled,     * or could not be cancelled for some other reason. If successful,     * and this task has not started when <tt>cancel</tt> is called,     * this task should never run.  If the task has already started,     * then the <tt>mayInterruptIfRunning</tt> parameter determines     * whether the thread executing this task should be interrupted in     * an attempt to stop the task.     *     * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this     *        task should be interrupted; otherwise, in-progress tasks are allowed     *        to complete.     *     * @return <tt>false</tt> if the task could not be cancelled,     *         typically because it has already completed normally;     *         <tt>true</tt> otherwise     *     * @see #isCancelled()     * @see #onCancelled()     */    public final boolean cancel(boolean mayInterruptIfRunning) {        return mFuture.cancel(mayInterruptIfRunning);    }    /**     * Waits if necessary for the computation to complete, and then     * retrieves its result.     *     * @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();    }    /**     * Waits if necessary for at most the given time for the computation     * to complete, and then retrieves its result.     *     * @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);    }    /**     * Executes the task with the specified parameters. The task returns     * itself (this) so that the caller can keep a reference to it.     *     * This method must be invoked on the UI thread.     *     * @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;//这是决定AsyncTask执行顺序逻辑的关键类,先pre,后doInBack,由back调用post        onPreExecute();        mWorker.mParams = params;        sExecutor.execute(mFuture);        return this;    }    /**     * This method can be invoked from {@link #doInBackground} to     * publish updates on the UI thread while the background computation is     * still running. Each call to this method will trigger the execution of     * {@link #onProgressUpdate} on the UI thread.     *     * @param values The progress values to update the UI with.     *     * @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);//表示post方法已经执行完毕        mStatus = Status.FINISHED;    }//由这个handler来处理后台runnable发送的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;        }    }}
通过代码分析了解了AsyncTask的内部执行逻辑,接下来对于线程池和缓冲队列进行研究