Android之AsyncTask源码分析(第三篇:执行任务)

(注意:本文基于API 28的源码分析,API 29上或其他平台的源码略有不同)

  

execute()方法分析(重载方法:参数为可变参数)

    @MainThread
    public final AsyncTask<Params, Progress, Result> execute(Params... params) {
        return executeOnExecutor(sDefaultExecutor, params);
    }

用于执行任务的方法传入的参数是可变参数,且类型取决于参数类型Params

1、将sDefaultExecutor,它是AsyncTask类持有的一个Executor对象,且用valatile修饰,保证可见性、保证有序性)、以及可变参数params同时传递到一个executeOnExecutor()方法中

2、向调用者返回AsyncTaskd对象

executeOnExecutor()方法的返回值是AsyncTask对象,它会返回给调用者

 

executeOnExecutor()方法分析

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

1、首先对AsyncTask对象持有的状态mStatus进行一个比较,如果状态不是Status.PENDING,会根据mStatus的状态是RUNNING或FINISHED状态抛出异常(注意:这里是一个AsyncTask对象只能执行一次execute方法的原因)AsyncTask对象持有的mStatus,它的默认值是Status.PENDING

2、正常运行的情况,AsyncTask对象的状态mStatus首先会被赋值为Status.RUNNING,然后调用onPreExecute()方法,这个onPreExecute()方法在主线程中执行,我们经常会重写它,在里面做一些任务前的执行的准备工作

3、将传入的可变参数params交由AsyncTask对象持有的WorkerRunnable对象mWorker的实例变量mParams负责保管

4、调用传入的Executor对象的execute方法,并且会把AsyncTask对象持有的FutureTask对象mFuture传了进去

注意:此时如果Executor对象为默认实现的sDefaultExecutor则会走到的execute()方法

5、返回当前AsyncTask对象

 

onPreExxecute()方法分析

    @MainThread
    protected void onPreExecute() {
    }

用于在任务开始前,做准备工作的方法,AsyncTask中是空的实现,我们会在子类中重写该方法

 

execute()方法分析(重载方法:传入Runnable对象)

 

        public synchronized void execute(final Runnable r) {
            mTasks.offer(new Runnable() {
                public void run() {
                    try {
                        r.run();
                    } finally {
                        scheduleNext();
                    }
                }
            });
            if (mActive == null) {
                scheduleNext(); //见下方
            }
        }

注意:该方法位于AsyncTask的静态内部类SerialExecutor中,最终传入的Runnable对象的run方法(FutureTask对象的run方法)会在线程池中得到执行

 

scheduleNext()方法分析

        protected synchronized void scheduleNext() {
            if ((mActive = mTasks.poll()) != null) {
                THREAD_POOL_EXECUTOR.execute(mActive);  //THREAD_POOL_EXECUTOR是线程池对象
            }
        }

 

execute()方法分析(属于AsyncTask类的方法)

 

    @MainThread
    public static void execute(Runnable runnable) {
        sDefaultExecutor.execute(runnable);
    }

该静态方法会将传入的Runnable对象传入到对应的sDefaultExecutor指向的对象的execute方法中(因sDefaultExecutor指向的对象是可以修改的)

 

枚举类Status分析

    public enum Status {
        /**
         * 指示任务尚未执行
         */
        PENDING,
        /**
         * 提示任务正在运行
         */
        RUNNING,
        /**
         * 提示AsyncTask#onPostExecute方法已经执行完毕
         */
        FINISHED,
    }

Status位于AsyncTask内部,表示AsyncTask对象的状态,一共3个状态,见注释

 

总结

1、execute(Params... params)在主线程中调用

2、execute(Executor e,Params... params)在主线程中调用

3、execute(Runnable runnable)在主线程中调用

4、因为AsyncTask对象就必须在主线程中创建

5、执行execute()方法后,onPreExecute方法先在主线程中调用,那么经常重写的doInBackground()方法、onPostExecute()方法在哪里被调用了呢?将在下一篇文章中解答

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值