AsyncTask源码分析

两个线程池:ThreadPoolExecutor (THREAD_POOL_EXECUTOR) SerialExecutor(SERIAL_EXECUTOR, sDefaultExecutor)
一个Handler: internalHandler

THREAD_POOL_EXECUTOR队列: BlockingQueue队列存放线程LinkedBlockingQueue128
sDefaultExecutor队列: ArrayDeque队列, 默认大小

//Queue接口
public abstract boolean add(E paramE); 
public abstract boolean offer(E paramE); 
public abstract E remove(); 
public abstract E poll(); 

Queue接口提供了以上几个方法。
看了ArrayDeque类的源码。有以下几点总结:
1)ArrayDeque有两个类属性,head和tail,两个指针。
2)ArrayDeque通过一个数组作为载体,其中的数组元素在add等方法执行时不移动,发生变化的只是head和tail指针,而且指针是循环变化,数组容量不限制。
3)offer方法和add方法都是通过其中的addLast方法实现,每添加一个元素,就把元素加到数组的尾部,此时,head指针没有变化,而tail指针加一,因为指针是循环加的,所以当tail追上head((this.tail = this.tail + 1 & this.elements.length - 1) == this.head)时,数组容量翻一倍,继续执行。
4)remove方法和poll方法都是通过其中的pollFirst方法实现,每移除一个元素,该元素所在位置变成null,此时,tail指针没有变化,而head指针加一,当数组中没有数据时,返回null。
5)因为ArrayDeque不是线程安全的,所以,用作堆栈时快于 Stack,在用作队列时快于 LinkedList。

执行过程: 当调用excute(Params... params)方法之后 excute 方法调用excuteOnExcutor()方法, excuteOnExcutor()判断状态RUNNING, FINISHED并相应抛出异常, 然后调用onPreExctue()方法

@MainThread
public final AsyncTask execute(Params... params) {
   //sDefaultExecutor----->exec
    return executeOnExecutor(sDefaultExecutor, params);
}
@MainThread
public final AsyncTask 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;
      //再通过传入的sDefaultExcutor即exec执行excute(), 
      //SericlaEcecutor 内部实现一个队列:ArrayDeque mTasks
      //每次sDefaultDecutor即exec执行execute(mFuture)执行下面代码
    exec.execute(mFuture);
    return this;
}

// SericalExecutor是串行执行的
private static class SerialExecutor implements Executor {
    final ArrayDeque mTasks = new ArrayDeque();
    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);
        }
    }
}

首先AsyncTask将传进Parmas参数封装成FutureTask对象AsyncTask的成员变量mFuture, 这里的mFuture 充当Runnable, 然后mFuture交给SericalExecutor的exceute执行, mFuture的运行并不是以thread运行的, 而是SericalExector将mFuture的run放到另起一个Runnable中执行然后offer到mTasks中并执行scheduleNext()来执行THREAD_POOL_EXECUTOR.execute()也就是把mTasks中的pop出一个Runnable拿出来运行, 来实现串行机制.

mFutureTask的run方法会调用mWorker的call()方法, 因此mWorker的call方法最终在线程池中执行

mWorker在AsyncTask构造函数中生成, 调用call时会设置mTaskInvoked为ture, 设置进程优先级为Process.THREAD_PRIORITY_BACKGROUND, 调用doInBackground()返回result传给postRuselt()

mWorker = new WorkerRunnable() {
    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;
    }
};

postResult()方法通过sHandler发送一个MESSAGE_POST_RESULT sHandler则调用result.mTask.finish(result.mData[0])

InternalHandler的实现
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;
        }
    }
}

InternalHandler sHandler是一个静态的handler在AsyncTask里面只存在一个, 为了能切换到UI线程, 因此需要它在UI线程里初始化, 也就是AsyncTask实例需要在UI线程里初始化.

这里看到还有个Message是MESSAGE_POST_PROGRESS
就是我在重写doInBackground执行耗时任务的时候每走一步发送一个进度publishProgress()调用

@WorkerThread
protected final void publishProgress(Progress... values) {
    if (!isCancelled()) {
        getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
                new AsyncTaskResult(this, values)).sendToTarget();
    }
}

进行更新UI进度的.
完成分析

你可能感兴趣的:(AsyncTask源码分析)