AsyncTask源码解析

我们从AsyncTask的excute方法看起,执行的是excuteOnExecutor方法
public final AsyncTask<ParamsProgressResult> execute(Params... params) {
    return executeOnExecutor( sDefaultExecutor, params);
}

这里传进去的是一个静态的sDefaultExecutor,声明如下:
private static volatile Executor  sDefaultExecutor SERIAL_EXECUTOR;

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

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

    protected synchronized void scheduleNext() {
        if (( mActive mTasks.poll()) !=  null) {
            THREAD_POOL_EXECUTOR.execute( mActive);
        }
    }
}
SerialExecutor是一个顺序执行器,在execute中通过ArrayDeque offer一个线程,将线程插入到队列的末尾。然后执行 scheduleNext取出ArrayDeque中的第一个元素,用 THREAD_POOL_EXECUTOR去执行。这里我们看下ArrayDeque的offer和poll方法API

offer(E e)
Inserts the specified element at the end of this deque.

poll()
Retrieves and removes the head of the queue represented by this deque (in other words, the first element of this deque), or returns  null if this deque is empty.
可以看出其实这里就是实现了一个队列的过程,那么为什么不用LinkList(JAVA提供的ArrayQueue为List实现)而用ArrayDeque呢,我们同样可以在API中找到答案,
This class is likely to be faster than  Stack  when used as a stack, and faster than  LinkedList  when used as a queue.
即这个 类很可能在用作堆栈时快于  Stack ,在用作队列时快于 LinkedList
所以AsyncTask在这里用ArrayDeque实现了一个顺序执行器,在execute的时候取出队列中第一个元素,交给
THREAD_POOL_EXECUTOR去执行即可。

然后我们看executeOnExecutor方法:

public final AsyncTask< ParamsProgressResult> 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;
}
首先AsyncTask的state必须为 PENDING状态,即对于AsyncTask的
public final AsyncTask<Params, Progress, Result> execute(Params... params)
这个方法,每个AsyncTask对象只可以执行1次,然后回调onPreExecute()方法。
下面我们需要关注 mWorkermFuture这两个变量。它们都是在构造器中初始化,代码如下:
/**
 * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
 */
public AsyncTask() {
    mWorker new WorkerRunnable< ParamsResult>() {
        public  Result call()  throws Exception {
            mTaskInvoked.set( true);

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

    mFuture new FutureTask< Result>( mWorker) {
        @Override
        protected void done() {
            try {
                final  Result result = get();

                postResultIfNotInvoked(result);
            }  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);
            }  catch (Throwable t) {
                throw new RuntimeException( "An error occured while executing "
                       "doInBackground()", t);
            }
        }
    };
}
可见 mFuture实现了一个FutureTask任务,在done方法中通过get()获取Result,并postResultIfNotInvoked该结果。
然后我们在看 mWorker postResult(doInBackground( mParams))在这里回调了doInBackground方法。
然后我们看postResult方法:

private  Result postResult( Result result) {
    Message message =  sHandler.obtainMessage( MESSAGE_POST_RESULT,
            new AsyncTaskResult< Result>( this, result));
    message.sendToTarget();
    return result;
}
sHandler声明如下:
private static final InternalHandler  sHandler new InternalHandler();

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

postResult方法为从 sHandler 获取一个Message,然后交给自己处理,即调用AsyncTask的finish方法,finish方法代码如下:

private void finish( Result result) {
    if (isCancelled()) {
        onCancelled(result);
    }  else {
        onPostExecute(result);
    }
    mStatus = Status. FINISHED;
}
如果被取消,则调用onCancelled回调,否则回调onPostExecute方法。
到这里为止,我们已经知道了AsyncTask的onPreExecute,doInBackground,onPostExecute,onCancelled分别在哪里回调的,那么onProgressUpdate方法是如何回调的呢,我们在用AsyncTask更新进度条的时候会在doInBackground中调用publishProgress方法,那么我们看下源码:

protected final void publishProgress( Progress... values) {
    if (!isCancelled()) {
        sHandler.obtainMessage( MESSAGE_POST_PROGRESS,
                new AsyncTaskResult< Progress>( this, values)).sendToTarget();
    }
}
可见此方法也为从 sHandler 中获取Message并发送给自身处理,而InternalHandler中通过Message的what信息判断,回调了onProgressUpdate方法。

到这里为止,AsyncTask算是分析完毕了,还有些细节的地方以后慢慢加上吧。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值