​ 首先我们使用AsyncTask时,一般是:

new AsyncTask(...).execute()
复制代码

我们看new AsyncTask(),它走的是:

  public AsyncTask() {this((Looper) null);}public AsyncTask(@Nullable Looper callbackLooper) {//创建一个handler到后面将子线程处理的消息传递给主线程,这个handler是基于主线程创建的mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()? getMainHandler(): new Handler(callbackLooper);
//创建了一个WorkerRunnable,它实现了Callable,这个后面会讲到mWorker = new WorkerRunnable<Params, Result>() {public Result call() throws Exception {mTaskInvoked.set(true);Result result = null;try {Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);//在子线程中处理异步任务result = doInBackground(mParams);Binder.flushPendingCommands();} catch (Throwable tr) {mCancelled.set(true);throw tr;} finally {postResult(result);}//将处理结果传递出去return result;}};//FutureTask是实现了RunnableFuture,Runnable和Future接口mFuture = new FutureTask<Result>(mWorker) {@Overrideprotected 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);}}};}复制代码

主要是创建了三个对象,mHandler,mWorker和mFuture,mHandler是将后面处理的结果发送到主线程;mWorker主要是实现Callable接口,并在call中调用doInBackground()方法处理任务;mFuture则是实现了RunnableFuture,Runnable和Future接口,最后在done中调用postResultIfNotInvoked()方法将处理结果传递出去。也就是主要弄清楚mWorker.call()以及mFuture.done()。下面我们分析他们分别在什么时候调用。接着往下看AsyncTask的execute():

 @MainThreadpublic final AsyncTask<Params, Progress, Result> execute(Params... params) {return executeOnExecutor(sDefaultExecutor, params);}@MainThreadpublic final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,Params... params) {......mStatus = Status.RUNNING;onPreExecute();mWorker.mParams = params;exec.execute(mFuture);return this;}
复制代码

我们可以看到调用AsyncTask.execute()是执行了executeOnExecutor(sDefaultExecutor, params);这个方法,我们看executeOnExecutor()方法,它执行了 onPreExecute(),对应我们应用中的异步任务前的准备操作,接着将params值传递 给mWorker,最后执行了 exec.execute(mFuture);这个exec就是上面传递进来的 sDefaultExecutor,也就是执行了sDefaultExecutor.execute()方法。sDefaultExecutor是什么呢?往下看:

private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
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);}}}
复制代码

sDefaultExecutor其实就是SerialExecutor,所以就是执行了SerialExecutor的execute(mFuture)方法,然后调用了 r.run()也就是mFuture.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 interruptsint s = state;if (s >= INTERRUPTING)handlePossibleCancellationInterrupt(s);}}
复制代码

Callable c = callable中的callable其实就是mWorker,因为我们在AsyncTask的构造方法中创建mFuture对象时将mWorker传递进去了: mFuture = new FutureTask(mWorker) ,我们看看FutureTask的构造方法:

  public FutureTask(Callable<V> callable) {if (callable == null)throw new NullPointerException();this.callable = callable;this.state = NEW;       // ensure visibility of callable}
复制代码

发现有 this.callable = callable,所以callable其实就是mWorker。我们接着看FutureTask的run方法,它调用了c.run(),也就是mWorker.run(),现在很清晰了,也就回调到最开始mWorker的run,调用doInBackground()方法等等。接着往下看,调用了 set(result)方法:

    protected void set(V v) {if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) {outcome = v;U.putOrderedInt(this, STATE, NORMAL); // final statefinishCompletion();}}
复制代码

将result赋值给了outcome。继续往下看,调用了finishCompletion():

  private void finishCompletion() {...done();...}
复制代码

调用了done()方法,是不是很熟悉,也就是我们之前mFuture的done()方法,接着在done()中调用postResultIfNotInvoked(get()):

public V get() throws InterruptedException, ExecutionException {int s = state;if (s <= COMPLETING)s = awaitDone(false, 0L);//返回report()的结果return report(s);}private V report(int s) throws ExecutionException {Object x = outcome;if (s == NORMAL)//将outcome返回,也就是对应的resultreturn (V)x;if (s >= CANCELLED)throw new CancellationException();throw new ExecutionException((Throwable)x);}private void postResultIfNotInvoked(Result result) {final boolean wasTaskInvoked = mTaskInvoked.get();if (!wasTaskInvoked) {postResult(result);}}
复制代码

调用get()返回了outcome也就是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;}...public void handleMessage(Message msg) {AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;switch (msg.what) {case MESSAGE_POST_RESULT:// There is only one resultresult.mTask.finish(result.mData[0]);break;case MESSAGE_POST_PROGRESS:result.mTask.onProgressUpdate(result.mData);break;}}...
复制代码

结果通过handler将消息传递到主线程,并执行了result.mTask.finish();我们接着看finish方法:

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

如果取消了就执行onCancelled(),否则执行onPostExecute()将结果回调到我们的应用当中。 接着我们看在doInBackground()中回调处理进度的方法publishProgress():

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

通过handler将任务进度传到主线程,我们看handleMessage(见上面的处理) result.mTask.onProgressUpdate(result.mData);是不是很熟悉,就是将进度回调到应用中,并且是在主线程中,可直接更新UI。很多很小的细节,可以再慢慢琢磨,先把大概的分析清楚,这就是AsyncTask的大致流程。

转载于:https://juejin.im/post/5c8a5b6bf265da2dbc59d103

Asynctask源码分析相关推荐

  1. 你真的了解AsyncTask吗?AsyncTask源码分析

    转载请注明出处:http://blog.csdn.net/yianemail/article/details/51611326 1,概述 Android UI是线程不安全的,如果想要在子线程很好的访问 ...

  2. 线程中task取消_Rust Async: async-task源码分析

    async-std是rust异步生态中的基础运行时库之一,核心理念是合理的性能 + 用户友好的api体验.经过几个月密集的开发,前些天已经发布1.0稳定版本.因此是时候来一次深入的底层源码分析.asy ...

  3. Android之AsyncTask源码分析(第五篇:execute方法只能执行一次的原因)

    (注意:本文基于API 28的源码分析,API 29上或其他平台的源码略有不同) 前言 当你调用AsyncTask对象的execute()方法时,突然发生崩溃--内心充满不解:java.lang.Il ...

  4. 【Android 异步操作】AsyncTask 异步任务 ( 参数简介 | 方法简介 | 使用方法 | AsyncTask 源码分析 )

    文章目录 一.AsyncTask 参数简介 二.AsyncTask 方法简介 三.AsyncTask 基本用法 四.AsyncTask 构造函数源码解析 五.AsyncTask 构造函数相关源码注释 ...

  5. android asynctask源码分析,Android通过Handler与AsyncTask两种方式动态更新ListView(附源码)...

    本文实例讲述了Android通过Handler与AsyncTask两种方式动态更新ListView的方法.分享给大家供大家参考,具体如下: 有时候我们需要修改已经生成的列表,添加或者修改数据,noti ...

  6. AsyncTask使用以及源码分析

    综述 在Android中,我们需要进行一些耗时的操作,会将这个操作放在子线程中进行.在子线程操作完成以后我们可以通过Handler进行发送消息,通知UI进行一些更新操作(具体使用及其原理可以查看And ...

  7. 【Android 电量优化】JobScheduler 源码分析 ( JobServiceContext 源码分析 | 闭环操作总结 | 用户提交任务 | 广播接收者接受相关广播触发任务执行 )★

    文章目录 一.JobServiceContext 引入 二.JobServiceContext 源码分析 三.用户在应用层如何使用 JobScheduler 四.用户提交任务 五.广播接收者监听广播触 ...

  8. 【Android 电量优化】JobScheduler 相关源码分析 ( JobSchedulerService 源码分析 | Android 源码在线网址推荐 )

    文章目录 一.JobScheduler 提交任务 schedule 方法源码分析 二.schedule(JobInfo job, int uId) 方法 三.scheduleAsPackage 方法 ...

  9. Android AsyncTask源码解读

    屡思路 1. 初始 AsyncTask AsyncTask 这个类的声明如下: public abstract class AsyncTask<Params, Progress, Result& ...

最新文章

  1. 定制iOS 7中的导航栏和状态栏
  2. 增加 processon 免费文件数
  3. 五种I/O 模式——阻塞(默认IO模式),非阻塞(常用语管道),I/O多路复用(IO多路复用的应用场景),信号I/O,异步I/O
  4. 十年沉淀,阿里云发布全球领先的对象存储OSS可用性SLA
  5. kdj买卖指标公式源码_通达信指标公式源码MACD背离KDJ背离指标
  6. 程序设计与算法----递归汉诺塔问题
  7. 小程序:微信小程序开发
  8. c语言 函数-斐波那契数列,c语言斐波那契数列递归法(示例代码)
  9. Basler千兆网相机使用相关设置
  10. CAD二次开发(VB)代码整理
  11. 关于信息墒与压缩编码基础的学习
  12. 【PAT】L1-050. 倒数第N个字符串【C语言实现】
  13. html怎么设置取消隐藏,使用Jquery或Javascript隐藏/取消隐藏html元素
  14. matlab中numden函数,numden函数 MATLAB里面numden函数有什么用?
  15. C#查找Excel()重复项
  16. 基于MATLAB的雷达的杂波模拟器
  17. 如何看电脑支持最大多少内存条?仅需一个命令
  18. IPEndPoint 和 EndPoint
  19. 单片机51实现计算器详细代码能自己运行
  20. 深入理解Linux虚拟内存管理(二)

热门文章

  1. Ubuntu 16.04 LTS GNOME版本下载
  2. Laravel之Eloquent ORM访问器调整器及属性转换
  3. Openfire 性能优化
  4. 数据库事务的四大特性和隔离级别
  5. OC高效率52之理解消息转发机制
  6. Yii中创建自己的Widget
  7. Yii学习笔记【2】
  8. 为Qt扩展QextSerialPort类
  9. android自定义文件选择,关于安卓自定义本地文件选择库的实现
  10. linux shell输出数字小数点前少了0_南京课工场IT培训:SHELL 超详细基础知识,适合新手小白(一)