Q:

How does AsyncTask SerialExecutor work? 

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

Above code snippet is from the  AsyncTask source code implementing the SerialExcutor, But I dont understand how exactly it works.  
when a new task arrives, it is put into the end of a ArrayDeque, the task on the top of the ArrayDeque get executed only when there is no other task is being executed currently. ( when mActive == null). 
So if a task is being executed when a new task arrive, there is nothing will be triggered, when the task finish executing, how the ArrayDeque know pop the next task on the top to execute it??? 

A:

Tasks are executed on a separate thread by THREAD_POOL_EXECUTOR that takes in a Runnable.  In this Runnable, when the running task finishes for some reason, scheduleNext() is called in the finally block.  If there are any tasks in the queue, the first one will be executed, otherwise the executor will be idle until the next call to execute().  Also, synchronized ensures that execute() and scheduleNext() cannot be run in separate threads at the same time.