AsyncTask 源码分析

我们在有异步任务时经常会使用 AsyncTask,都知道是 Handler + 线程池的异步框架,那原理是什么呢?怎么做到按顺序执行 onPreExecute() doInBackground() 等方法的呢,本篇文章会回答这些问题。

下面从构造方法开始看

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

AsyncTask 最终会执行到下面这个构造方法

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


可以看到在构造方法里,赋值了三个成员变量 mHandler,mWorker,mFutre。我们一个一个来分析

Handler

public AsyncTask(@Nullable Looper callbackLooper) {
    mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
            ? getMainHandler()
            : new Handler(callbackLooper);

如果当构造方法里的 callbackLooper 为 null 或者该 lopper 是在主线程中,mHandler 为主线程的 Handler ,否则就是该 Looper 所在线程的 Handler。

然后来看 mWorker,它是一个 WorkerRunnable 


WorkerRunnable

WorkerRunnable 是什么呢

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

是实现了 Callable 接口的抽象类

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

并重写了 call() 方法

public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

Callable 接口和 Runnable 接口一个很大的区别就是 Callable 接口有返回值

再看 mFutrure,它是 FutureTask 类


FutureTask

public class FutureTask<V> implements RunnableFuture<V> {

FutureTask 类实现了 RunnableFuture接口

public interface RunnableFuture<V> extends Runnable, Future<V> {
    /**
     * Sets this Future to the result of its computation
     * unless it has been cancelled.
     */
    void run();
}


RunnableFuture 又继承了 Runnable 和 Future 接口
Runnable 接口只有一个 run() 方法我们都知道
Future 接口的部分注释说明如下

A {@code Future} represents the result of an asynchronous
 * computation.  Methods are provided to check if the computation is
 * complete, to wait for its completion, and to retrieve the result of
 * the computation.  The result can only be retrieved using method
 * {@code get} when the computation has completed, blocking if
 * necessary until it is ready.  Cancellation is performed by the
 * {@code cancel} method.  Additional methods are provided to
 * determine if the task completed normally or was cancelled. Once a
 * computation has completed, the computation cannot be cancelled.
 * If you would like to use a {@code Future} for the sake
 * of cancellability but not provide a usable result, you can
 * declare types of the form {@code Future<?>} and
 * return {@code null} as a result of the underlying task.

注释说明了 Future 接口是可以获取异步任务执行结果的,也可以判断当前任务状态以及取消任务等操作。提供了 cancel() get() isCanceled() idDone() 等方法

再来看给 mFuture 赋值的地方

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


在 new 的时候把 mWorker,即上面的 Callable 传入作为构造参数,并且重写了 done() 方法
来看构造方法对 Callable 做了什么

public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

仅仅是将 callable 赋值,并在 FutureTask 的 run() 中执行 callable.call()

public void run() {
        ...
        try {
            //使用构造函数中的 callable
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    //执行 callable
                    result = c.call();
                    ran = true;
                } 
        ...

所以当运行 FutureTask 的run()时,也就执行了前面 mWorker 的 callable

并且重写了 done() 方法,先看下 FutureTask 中的 done() 方法

/**
     * Protected method invoked when this task transitions to state
     * {@code isDone} (whether normally or via cancellation). The
     * default implementation does nothing.  Subclasses may override
     * this method to invoke completion callbacks or perform
     * bookkeeping. Note that you can query status inside the
     * implementation of this method to determine whether this task
     * has been cancelled.
     */
    protected void done() { }

是一个空实现,注释中也说明了当任务执行完毕或者被取消后会调用该方法,mFuture 的 done() 执行的内容后面再分析;至此 AsyncTask 的构造方法分析完毕了,然后分析运行时执行的 execute() 方法。

public final AsyncTask<Params, Progress, Result> execute(Params... params) {
        return executeOnExecutor(sDefaultExecutor, params);
    }
    
    public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
            Params... params) {
        //检查 status,只能运行一次
        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()
        onPreExecute();

        mWorker.mParams = params;
        //调用 executor 的 execute()
        exec.execute(mFuture);

        return this;
    }

在 execute() 方法我们看到先对状态进行检查,然后调用onPreExecute(),并调用 exec.execute(mFuture);
exec 是 sDefaultExecutor,sDefaultExecutor 是SerialExecutor实例,我们来看这个类

private static class SerialExecutor implements Executor {
        final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
        Runnable mActive;

        public synchronized void execute(final Runnable r) {
            //添加 Runnable 到 mTasks 的队尾
            mTasks.offer(new Runnable() {
                public void run() {
                    try {
                        r.run();
                    } finally {
                        scheduleNext();
                    }
                }
            });
            if (mActive == null) {
                scheduleNext();
            }
        }

        //用线程池执行 mTasks 中的 Runnable
        protected synchronized void scheduleNext() {
            if ((mActive = mTasks.poll()) != null) {
                THREAD_POOL_EXECUTOR.execute(mActive);
            }
        }
    }

他的 execute(Runnable r)传入的参数是 mFuture 这个 Runnable,
mTasks是明显是一个队列,mTasks.offer(Runnable r) 做的是将 runnable 添加到队尾。所以 execute() 将传进来的 mFuture 再封装成 Runnable,然后用线程池执行 mTasks 中的 Runnable
。然后我们再来看这个线程池

private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    // We want at least 2 threads and at most 4 threads in the core pool,
    // preferring to have 1 less than the CPU count to avoid saturating
    // the CPU with background work
    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;
    
    private static final BlockingQueue<Runnable> sPoolWorkQueue =
            new LinkedBlockingQueue<Runnable>(128);

    /**
     * An {@link Executor} that can be used to execute tasks in parallel.
     */
    public static final Executor THREAD_POOL_EXECUTOR;

    static {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
                sPoolWorkQueue, sThreadFactory);
        threadPoolExecutor.allowCoreThreadTimeOut(true);
        THREAD_POOL_EXECUTOR = threadPoolExecutor;
    }

AsyncTask 创建了一个线程池,核心线程最多为4个,最大队列长度为128,当用线程池执行 execute 时,就开始了真正的后台任务。

至此我们小结一下,线程池 execute(runnable) 的 Runnable 即为经过封装的 FutureTask,前面看了 FutureTask 的 run() 又会调用 callable 的 call(), callable 是创建 FutureTask的参数,即 mWorker。所以也就是运行了 mWorker 的call(),我们把代码再复制过来看

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

这里看到调用了 doInBackground() ,并在 finnaly 执行了 postResult() 做完成后的操作

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

看到是用 handler 发送了一条 MESSAGE_POST_RESULT 的消息,再看 handler 的 handleMessage 怎么处理的

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

对 MESSAGE_POST_RESULT 的处理是调用 mTask 的 finish(),mTask 为 AsyncTask 本身。

private void finish(Result result) {
        if (isCancelled()) {
            onCancelled(result);
        } else {
            onPostExecute(result);
        }
        mStatus = Status.FINISHED;
    }

很清晰的表明了是否是取消,如果是执行完毕就调用我们重写的 onPostExecute()。

至此还没完,到这儿执行完了 mWorker 的 call(),这是由 FutureTask 调用的,FutureTask 还有自己执行完调用的方法,done()

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

执行的是 get() 返回值,然后调用 postResultIfNotInvoked()
get() 会阻塞线程直到执行完毕返回。所以当执行完毕或者取消时才会执行 postResultIfNotInvoked() 

private void postResultIfNotInvoked(Result result) {
        //获取 mTaskInvoked 是否被 set
        final boolean wasTaskInvoked = mTaskInvoked.get();
        //如果没被 set true 就执行 postResult 结束
        if (!wasTaskInvoked) {
            postResult(result);
        }
    }

上面我们看到是在 worker 的 call() 对 mTaskInvoked set 值的;
所以当任务被取消时才会调用到这里,postResult 即 call() 的 finally 执行的结束任务,调用 postExecute() ;到这里就是 Asynctask 的整体执行流程源码分析了。

再补充一个在过程中更新的过程,我们在需要更新时会调用 publishProgress()

protected final void publishProgress(Progress... values) {
        if (!isCancelled()) {
            getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
                    new AsyncTaskResult<Progress>(this, values)).sendToTarget();
        }
    }

我们看到也是用 handler 发送了一条消息,在 handleMessage 中处理

case MESSAGE_POST_PROGRESS:
                    result.mTask.onProgressUpdate(result.mData);
                    break;

做的是调用我们重写的 onProgressUpdate(),因为 handler 是在 UI 线程中的,所以我们的 onPostExecute() 和 onProgressUpdate() 都可进行 UI 更新的操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
蛋白质是生物体中普遍存在的一类重要生物大分子,由天然氨基酸通过肽键连接而成。它具有复杂的分子结构和特定的生物功能,是表达生物遗传性状的一类主要物质。 蛋白质的结构可分为四级:一级结构是组成蛋白质多肽链的线性氨基酸序列;二级结构是依靠不同氨基酸之间的C=O和N-H基团间的氢键形成的稳定结构,主要为α螺旋和β折叠;三级结构是通过多个二级结构元素在三维空间的排列所形成的一个蛋白质分子的三维结构;四级结构用于描述由不同多肽链(亚基)间相互作用形成具有功能的蛋白质复合物分子。 蛋白质在生物体内具有多种功能,包括提供能量、维持电解质平衡、信息交流、构成人的身体以及免疫等。例如,蛋白质分解可以为人体提供能量,每克蛋白质能产生4千卡的热能;血液里的蛋白质能帮助维持体内的酸碱平衡和血液的渗透压;蛋白质是组成人体器官组织的重要物质,可以修复受损的器官功能,以及维持细胞的生长和更新;蛋白质也是构成多种生理活性的物质,如免疫球蛋白,具有维持机体正常免疫功能的作用。 蛋白质的合成是指生物按照从脱氧核糖核酸(DNA)转录得到的信使核糖核酸(mRNA)上的遗传信息合成蛋白质的过程。这个过程包括氨基酸的活化、多肽链合成的起始、肽链的延长、肽链的终止和释放以及蛋白质合成后的加工修饰等步骤。 蛋白质降解是指食物中的蛋白质经过蛋白质降解酶的作用降解为多肽和氨基酸然后被人体吸收的过程。这个过程在细胞的生理活动中发挥着极其重要的作用,例如将蛋白质降解后成为小分子的氨基酸,并被循环利用;处理错误折叠的蛋白质以及多余组分,使之降解,以防机体产生错误应答。 总的来说,蛋白质是生物体内不可或缺的一类重要物质,对于维持生物体的正常生理功能具有至关重要的作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值