AsyncTask的执行流程及其细节点

来源:互联网 发布:java web创意项目 编辑:程序博客网 时间:2024/06/07 01:54

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.

 

        

0 0
原创粉丝点击