AsyncTask的执行流程及其细节点

AsyncTask的执行流程,完全根据developer在调用时的步骤进行分析。

       首先开发者会建立一个AsyncTask的实例

     AsyncTask asyncTask = new AsyncTaskImpl();
这个构造函数会调到AsyncTask的构造函数,在AsyncTask的构造函数中做了如下操作:

<span style="white-space:pre">	</span><span style="font-size:18px;">mWorker = new WorkerRunnable<Params, Result>() {
            public Result call() throws Exception {
                mTaskInvoked.set(true);

                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                //noinspection unchecked
                return postResult(doInBackground(mParams));
            }
        };

        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 occured while executing doInBackground()",
                            e.getCause());
                } catch (CancellationException e) {
                    postResultIfNotInvoked(null);
                }
            }</span>
     <span style="font-size:18px;">   };</span>
主要就是初始化了mWorker(WorkerRunnable),mFuture(FutureTask)。并且把mWorker的值传递给了mFuture。

这两个变量在后面会用到,先记着。

     然后会在调用asyncTask.execute(Params,Progress,Result);

     这里面会执行如下代码:

    return executeOnExecutor(sDefaultExecutor, params);
   然后去执行上面的方法,这个方法前面先判断了一下当前这个AsyncTask的状态,如果mStatus!=Pending的话,就会抛异常,否则就把mStatus=Pending,执行onPreExecute(),然后会调用如下:

    exec.execute(mFuture);
     这个exec就是sDefaultExecutor,查看赋值,发现属于SerialExecutor类,内部类。

     那就查看这个类,会执行execute()方法

    public synchronized void execute(final Runnable r) {
            mTasks.offer(new Runnable() {
                public void run() {
                    try {
                        r.run();
                    } finally {
                        scheduleNext();
                    }
                }
            });
            if (mActive == null) {
                scheduleNext();
            }
        }
其中tasks是一个ArrayDaque<Runnable>。这个方法会执行runnable的run,而这个runnable就是mFuture.

        mFuture属于FutureTask implements RunnableFuture extends Runnable的。

查看mFuture的run方法,如下: 

        ....
       try {
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                   <span style="color:#ff0000;"> result = c.call();</span>
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex);
                }
                if (ran)
                    set(result);
            }
其中会调用callable.call()方法,这个callable是在构造FutureTask时传递的,而FutureTask实例的构造就是之前提到的在AsyncTask的构造函数中进行的,其中是把mWorker作为callable传递了进去,本质上就是调用了mWorker.call()方法,而这个方法的定义也是在AsyncTask的构造函数中进行的。

mWorker是WorkerRunnable implements Callable.

mWorker的call()方法最关键的一句是最后一句,如下:

     return postResult(doInBackground(mParams));
       首先会回调doInBackground(),这个call方法是在非UI Thread进行的。执行完毕后,会在执行postResult()方法。

这个方法代码如下:

     private Result postResult(Result result) {
        @SuppressWarnings("unchecked")
        Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
                new AsyncTaskResult<Result>(this, result));
        message.sendToTarget();
        return result;
    }
     通过一个message+Handler机制,把消息传递给这个handler。就是InternalHandler。

     可见AsyncTask内部线程间的通信也是利用handler来进行的,ui-child通过callable来执行,从child-ui通过InternalHandler执行。

    下面看InternalHandler的代码:

   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;
            }
        }
如果msg.what = MESSAGE_POST_PROGRESS---此时一定是调用了publishProgress并且isCancelled()返回了false,则回调onProgressUpdate()方法。

         而postResult()中的msg.what = MESSAGE_POST_RESULT,因此会执行result.mTask.finish()方法,查看代码如下:

       private void finish(Result result) {
            if (isCancelled()) {
                onCancelled(result);
            } else {
                onPostExecute(result);
            }
            mStatus = Status.FINISHED;
        }
    会先判断是不是cancel()了,如果有就执行onCancelled(),否则回调到onPostExecute()方法,并且把状态设置为finished.



  一整套流程就结束了,基本就是

1)构造函数里

2)execute()--回调到executeOnExecutor()----判断status状态,然后设置为running

3)执行serialExecutor.run();

        4)也就是执行mFuture.run();

        5)也就是执行mWorker.call();

        6)回调到postResult(doInBackground())

        7)通过handler发消息,回调finish()

        8)判断是不是cancel了,是的话执行onCancelled()否则执行OnPostExecute()---设置status状态为finished.

 

        

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值