Android AsyncTask源码学习

版权声明:本文为博主原创文章,可以随意转载,但是必须在开头标明出处。 https://blog.csdn.net/qq_29951983/article/details/79509962

AsyncTask如何使用这篇文章就不说了,网上很多,主要学习下源码,增长下见识。

TestAsyncTask test = new TestAsyncTask();
test.execute("aaa");
class TestAsyncTask extends AsyncTask<String,Integer,Long> {

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

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
        }

        @Override
        protected void onPostExecute(Long aLong) {
            super.onPostExecute(aLong);
        }
    }

首先new了一个AsyncTask对象,在构造函数中发现了如下代码:

public AsyncTask() {
        this((Looper) null);
    }
public AsyncTask(@Nullable Looper callbackLooper) {
        mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
            ? getMainHandler()
            : new Handler(callbackLooper);

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

        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 occurred while executing doInBackground()",
                            e.getCause());
                } catch (CancellationException e) {
                    postResultIfNotInvoked(null);
                }
            }
        };
    }
  1. 初始化了一个Handler,用于以后发消息。
  2. 初始化了一个WorkerRunnable对象,这个对象实现了Callable接口。
  3. 初始化了一个FutureTask对象,并且将WorkerRunnable对象传入进去。
    当运行test.execute(“aaa”)时:return executeOnExecutor(sDefaultExecutor, params);
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;
    }

先会调用AsyncTask的onPreExecute方法,该方法可以做一些初始化的操作。
mWorker.mParams = params; 将WorkerRunnable对象里面的泛型Params[]赋值。
调用exec.execute(mFuture); exec对象的execute方法。
这里的exec对象为:
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;

该SerialExecutor对象实现了Executor接口。
Executor概述:
执行提交的Runnable任务的对象。 这个接口提供了一种将任务提交与每个任务如何运行的机制解耦的方式。
例子:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        testExecutor();
    }

    private void testExecutor() {
        Executor executor = new ExecutorTest();
        executor.execute(new RunnableTest1());
        executor.execute(new RunnableTest2());
    }

    class ExecutorTest implements Executor {

        @Override
        public void execute(@NonNull Runnable command) {
            if (command instanceof RunnableTest1) {
                command.run();
            } else {
                new Thread(command).start();
            }
        }
    }

    class RunnableTest1 implements Runnable {

        @Override
        public void run() {
            System.out.println("RunnableTest1="+Thread.currentThread().getName());
        }
    }

    class RunnableTest2 implements Runnable {

        @Override
        public void run() {
            System.out.println("RunnableTest2="+Thread.currentThread().getName());
        }
    }

输出:

I/System.out: RunnableTest1=main
I/System.out: RunnableTest2=Thread-588

书接上文

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

这个类的主要作用就是同步执行,这可以作为一个学习的重点,当你学习源码的时候发现好的代码逻辑你可以(抄)记下来。
例如多个线程处理同一个对象你可以采用上面的方式:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final Executor executor = new SerialExecutor(new DirectExecutor());
        final RunnableTask1 runnableTask1 = new RunnableTask1();
        for (int i = 20; i >= 0; i--) {
            new Thread() {
                @Override
                public void run() {
                    executor.execute(runnableTask1);
                }
            }.start();
        }
    }

    class DirectExecutor implements Executor {
        public void execute(Runnable r) {
            new Thread(r).start();
        }
    }

    class SerialExecutor implements Executor {
        final Queue<Runnable> tasks = new ArrayDeque<Runnable>();
        final Executor executor;
        Runnable active;

        SerialExecutor(Executor executor) {
            this.executor = executor;
        }

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

        protected synchronized void scheduleNext() {
            if ((active = tasks.poll()) != null) {
                executor.execute(active);
            }
        }
    }

    private class RunnableTask1 implements Runnable {
        int i = 20;

        @Override
        public void run() {
            System.out.println("RunnableTask1.run  " + i--);
        }
    }
}

输出:

03-10 18:45:43.035 9442-9461/? I/System.out: RunnableTask1.run  20
03-10 18:45:43.035 9442-9466/? I/System.out: RunnableTask1.run  19
03-10 18:45:43.035 9442-9469/? I/System.out: RunnableTask1.run  18
03-10 18:45:43.035 9442-9470/? I/System.out: RunnableTask1.run  17
03-10 18:45:43.035 9442-9471/? I/System.out: RunnableTask1.run  16
03-10 18:45:43.045 9442-9472/? I/System.out: RunnableTask1.run  15
03-10 18:45:43.045 9442-9475/? I/System.out: RunnableTask1.run  14
03-10 18:45:43.045 9442-9483/? I/System.out: RunnableTask1.run  13
03-10 18:45:43.045 9442-9485/? I/System.out: RunnableTask1.run  12
03-10 18:45:43.045 9442-9487/? I/System.out: RunnableTask1.run  11
03-10 18:45:43.045 9442-9488/? I/System.out: RunnableTask1.run  10
03-10 18:45:43.045 9442-9490/? I/System.out: RunnableTask1.run  9
03-10 18:45:43.045 9442-9491/? I/System.out: RunnableTask1.run  8
03-10 18:45:43.045 9442-9492/? I/System.out: RunnableTask1.run  7
03-10 18:45:43.045 9442-9493/? I/System.out: RunnableTask1.run  6
03-10 18:45:43.045 9442-9494/? I/System.out: RunnableTask1.run  5
03-10 18:45:43.045 9442-9495/? I/System.out: RunnableTask1.run  4
03-10 18:45:43.045 9442-9496/? I/System.out: RunnableTask1.run  3
03-10 18:45:43.055 9442-9497/? I/System.out: RunnableTask1.run  2
03-10 18:45:43.055 9442-9498/? I/System.out: RunnableTask1.run  1
03-10 18:45:43.055 9442-9499/? I/System.out: RunnableTask1.run  0

书接上文:
这里THREAD_POOL_EXECUTOR 是一个线程池。
会执行mFuture = new FutureTask<Result>(mWorker) 这个对象的run方法,因为FutureTask也是实现了Runnable接口的。
但是你会发现new FutureTask对象并没有run方法,那是因为源码没有重写。

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 occurred while executing doInBackground()",
                            e.getCause());
                } catch (CancellationException e) {
                    postResultIfNotInvoked(null);
                }
            }
        };

FutureTask的run方法会调用其父类。

mFuture = new FutureTask<Result>(mWorker) {
            @Override
            public void run() {
                super.run();
            }
        };

可以看到,父类的run方法,最终会调用Callable对象的call()方法。

  public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }
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);
        }
    }

调用的call方法也就是

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

WorkerRunnable对象里面的call()方法;记住这时线程调用的,所以现在在非主线程中工作。
mTaskInvoked.set(true); 将mTaskInvoked对象设置为true,这是一个线程安全的改变。
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 设置了线程的安全级别。
重点 result = doInBackground(mParams); 调用了AsnycTask对象的doInBackground方法,该方法是运行在非UI线程中的,将结果返回给result变量,然后返回。
在finally中调用了

private Result postResult(Result result) {
        @SuppressWarnings("unchecked")
        Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
                new AsyncTaskResult<Result>(this, result));
        message.sendToTarget();
        return result;
    }

这里面getHandler就是在构造方法中初始化的Handler,运行在UI线程中。传递了一个what=MESSAGE_POST_RESULT的类型。

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

将结果封装为一个AsyncTaskResult对象。
这里面有两个what
MESSAGE_POST_RESULT:

 private void finish(Result result) {
        if (isCancelled()) {
            onCancelled(result);
        } else {
            onPostExecute(result);
        }
        mStatus = Status.FINISHED;
    }

判断是否调用了cancel()方法,如果调用了cancel()方法,将永远也运行不到onPostExecute()方法。

Attempts to cancel execution of this task. This attempt will fail if the task has already completed, already been cancelled, or could not be cancelled for some other reason. If successful, and this task has not started when cancel is called, this task should never run. If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.
Calling this method will result in onCancelled(Object) being invoked on the UI thread after doInBackground(Object[]) returns. Calling this method guarantees that onPostExecute(Object) is never invoked. After invoking this method, you should check the value returned by isCancelled() periodically from doInBackground(Object[]) to finish the task as early as possible.
试图取消执行此任务。 如果任务已完成,已被取消或因其他原因无法取消,此尝试将失败。 如果成功,并且此任务在调用取消时尚未开始,则此任务不应运行。 如果任务已经开始,则mayInterruptIfRunning参数确定执行此任务的线程是否应该中断以试图停止任务。
调用此方法将导致在doInBackground(Object [])返回后在UI线程上调用onCancelled(Object)。 调用此方法可确保永不调用onPostExecute(Object)。 调用此方法后,应该从doInBackground(Object [])中定期检查isCancelled()返回的值,以尽早完成任务。


public final boolean cancel(boolean mayInterruptIfRunning) {
        mCancelled.set(true);
        return mFuture.cancel(mayInterruptIfRunning);
    }

如果用户没调用cancel方法,则会调用onPostExecute()方法,这个方法也是在UI线程中。
MESSAGE_POST_PROGRESS:
该what,是在publishProgress方法中调用。

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

最后调用onProgressUpdate()方法,用于用户更新进度,也是在UI线程中。
就这样,整个AsyncTask的调用流程就结束了。
书接上文

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

在调用完c.call(); 方法时,将返回值赋给了result,将ran设置为true。然后执行了set(result); 方法。

 protected void set(V v) {
        if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) {
            outcome = v;
            U.putOrderedInt(this, STATE, NORMAL); // final state
            finishCompletion();
        }
    }

将处理结果给了outcome
该对象可以调用get方法

 public V get() throws InterruptedException, ExecutionException {
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    }
private V report(int s) throws ExecutionException {
        Object x = outcome;
        if (s == NORMAL)
            return (V)x;
        if (s >= CANCELLED)
            throw new CancellationException();
        throw new ExecutionException((Throwable)x);
    }

最后调用了finishCompletion 方法:

private void finishCompletion() {
        // assert state > COMPLETING;
        for (WaitNode q; (q = waiters) != null;) {
            if (U.compareAndSwapObject(this, WAITERS, q, null)) {
                for (;;) {
                    Thread t = q.thread;
                    if (t != null) {
                        q.thread = null;
                        LockSupport.unpark(t);
                    }
                    WaitNode next = q.next;
                    if (next == null)
                        break;
                    q.next = null; // unlink to help gc
                    q = next;
                }
                break;
            }
        }

        done();

        callable = null;        // to reduce footprint
    }

当整个流程都处理完之后调用来了done方法,该方法是一个空实现。
所以,在源码中:

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 occurred while executing doInBackground()",
                            e.getCause());
                } catch (CancellationException e) {
                    postResultIfNotInvoked(null);
                }
            }
        };

重写了done方法,并且调用了get()方法取出处理的结果。

 private void postResultIfNotInvoked(Result result) {
        final boolean wasTaskInvoked = mTaskInvoked.get();
        if (!wasTaskInvoked) {
            postResult(result);
        }
    }

final boolean wasTaskInvoked = mTaskInvoked.get(); 因为在调用call的时候将mTaskInvoked设为了true,所以就不在进行处理了。

微信公众号:
这里写图片描述
QQ群:365473065

猜你喜欢

转载自blog.csdn.net/qq_29951983/article/details/79509962