(源码阅读)源码分析之AsyncTask

     

             在深入码字之后越发觉得源码那么重要,于是开始了源码阅读之旅,下面来走进Android源码的世界。

AsyncTask源码分析---------------------------------------------------------------------------------------
AsyncTask基本使用
AsyncTask asyncTask = new AsyncTask<Void, Void, Void>() {
    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
    }

    @Override
    protected Void doInBackground(Void... params) {
        return null;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }
};
asyncTask.execute();

证明AsyncTask只能使用一次的代码
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;
}

最后调用了exec.execute(mFuture),里面传递了一个mFuture对象,根据这个继续看源码
public class FutureTask<V> implements RunnableFuture<V> {
这个也是实现了一个RunnableFuture,然而这个也是继承于Runnable的

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

这个时候我们去看FutureTask的run方法
public void run() {
    if (state != NEW ||
        !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread()))
        return;
    try {
        Callable<V> c = callable;
        if (c != null && state == NEW) {
            V result;
            boolean ran;
            try {
                result = c.call();
                ran = true;
            } catch (Throwable ex) {
                result = null;
                ran = false;
                setException(ex);
            }
            if (ran)
                set(result);
        }
    } finally {
        // runner must be non-null until state is settled to
        // prevent concurrent calls to run()
        runner = null;
        // state must be re-read after nulling runner to prevent
        // leaked interrupts
        int s = state;
        if (s >= INTERRUPTING)
            handlePossibleCancellationInterrupt(s);
    }

因为这里有一个callable对象,此刻的callable对象就是最开始的AsyncTask传过来的mWork对象,在run方法里调用了c.call();所以这个时候我们去查看AsyncTask下的mWord的call()方法
public AsyncTask() {
    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()方法的同时,我们终于看到了doInBackground()方法。执行完doInBackground()方法我们拿到了result,然后可以看到执行一个postResult方法,我们在根据这个方法走下去看。
private Result postResult(Result result) {
    @SuppressWarnings("unchecked")
    Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
            new AsyncTaskResult<Result>(this, result));
    message.sendToTarget();
    return result;
}

postResult调用了message.sendToTarget(),实际上是通过了Handler发送一个消息,这个时候线程也切换到了主线程。

private static class InternalHandler extends Handler {
    public InternalHandler() {
        super(Looper.getMainLooper());
    }

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


此时,到这里AsyncTask流程基本走完了,执行完finish方法之后。就会调用onCancelled,否则就是onPostExecute();
最后总结:AysncTask方法一旦调用excute()就会去判断当前状态,state默认是PENGING,状态不太就会抛出异常,同时也证明了AsyncTask的确只能被调用一次,判断完之后就会将状态置为Running,然后就会执行onPreExcute();开启一个线程去执行doInBackground();在doInBackground()执行完之后,会利用Handler去发送一个Message切换到主线程,然后执行onPostExcute();最后把状态置为finish。

猜你喜欢

转载自blog.csdn.net/guim_007/article/details/72972467