在我学习 AsyncTask 原理之前,我觉得 Retrofit+Rxjava 已经挺好用的了,就没有必要去用或者了解 AsyncTask 了。说真的我已经几百年没有用过 AsyncTask 了。但是我觉得存在即是合理的。那么下面说说为什么:
- AsyncTask 是通过线程池来实现的,在这一点上减少了新建线程和销毁线程的开销,减少了内存的使用。这一点在我们日常开发过程中是要学习的。
- AsyncTask 封装了Threan 和 Handler 便于前台和后台线程的切换。
- 使用范型参数,这对于我们的实际开发也是很有启发意义的。
- 对于我来说,也是阅读源码的开端,有点意义。
基本使用方法
首先得新建一个 class 去实现 AsyncTask:
class MyAsynTask extends AsyncTask<String, Integer, String> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(String... params) { publishProgress(55); return "zone"; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); } @Override protected void onPostExecute(String s) { Log.d("zoneLog", "onPostExecute: " + s); super.onPostExecute(s); } @Override protected void onCancelled() { super.onCancelled(); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
具体的调用:
MyAsynTask myAsynTask = new MyAsynTask(); myAsynTask.execute();
在下面的学习中,我建议打开 AndroidStudio 跟着走,不太清楚的地方好点进源码看个究竟。那么我们从 AsyncTask 的执行方法 execute() 开始。
@MainThread public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }
从上面这段代码得知,execute() 又调用了 executeOnExecutor() ,那么多出来的参数 sDefaultExecutor 是什么鬼?继续按住 ctrl + 鼠标单击,进去看看。
public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
ok,从上面看出,sDefaultExecutor 参数就是一个线程池。接着继续往下走,看看 executeOnExecutor()
@MainThread 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; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
mFuture 是 FutureTask 的实例,他的继承关系如下:
class FutureTask<V> implements RunnableFuture<V>interface RunnableFuture<V> extends Runnable, Future<V>
ok,有了上面的铺垫,我们就来看看线程池的执行过程:
下面的 execute() 方法,也就是对应着这个地方 – > exec.execute(mFuture);
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); } } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
FutureTask 最顶层实现了 Runnable,所以会有 run() 方法,在 run() 中会调用 mWorker 的 call() 方法,那么 mWorker 是什么鬼呢?如下: mWorker 是在 AsyncTask 的构造方法中实例化的
mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true);Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); Result result = doInBackground(mParams); Binder.flushPendingCommands(); return postResult(result); } };
上面这段代码,最终 return postResult(result) ,那么我们进去看postResult(result) 。
private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; }
上面这段代码通过 handler 发送了消息。且看看 handleMessage() 是如何处理这个消息的。代码如下:
public void handleMessage(Message msg) { AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj; switch (msg.what) { case MESSAGE_POST_RESULT: result.mTask.finish(result.mData[0]); break; case MESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData); break; } }
通过查看,我们知道,handleMessage() 又调用了 mTask 的 finish() 。且看看 finish() 里面又调用了什么?代码如下:
private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; }
一路下来,下面四个方法的具体调用也找到了出处,对 AsyncTask 原理也有了初步的了解,这次的探索也就到这里了。
@Override protected void onPreExecute() { } @Override protected String doInBackground(String... params) { } @Override protected void onPostExecute(String s) { } @Override protected void onCancelled() { }