Asynctask源码分析
首先我们使用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源码分析相关推荐
- 你真的了解AsyncTask吗?AsyncTask源码分析
转载请注明出处:http://blog.csdn.net/yianemail/article/details/51611326 1,概述 Android UI是线程不安全的,如果想要在子线程很好的访问 ...
- 线程中task取消_Rust Async: async-task源码分析
async-std是rust异步生态中的基础运行时库之一,核心理念是合理的性能 + 用户友好的api体验.经过几个月密集的开发,前些天已经发布1.0稳定版本.因此是时候来一次深入的底层源码分析.asy ...
- Android之AsyncTask源码分析(第五篇:execute方法只能执行一次的原因)
(注意:本文基于API 28的源码分析,API 29上或其他平台的源码略有不同) 前言 当你调用AsyncTask对象的execute()方法时,突然发生崩溃--内心充满不解:java.lang.Il ...
- 【Android 异步操作】AsyncTask 异步任务 ( 参数简介 | 方法简介 | 使用方法 | AsyncTask 源码分析 )
文章目录 一.AsyncTask 参数简介 二.AsyncTask 方法简介 三.AsyncTask 基本用法 四.AsyncTask 构造函数源码解析 五.AsyncTask 构造函数相关源码注释 ...
- android asynctask源码分析,Android通过Handler与AsyncTask两种方式动态更新ListView(附源码)...
本文实例讲述了Android通过Handler与AsyncTask两种方式动态更新ListView的方法.分享给大家供大家参考,具体如下: 有时候我们需要修改已经生成的列表,添加或者修改数据,noti ...
- AsyncTask使用以及源码分析
综述 在Android中,我们需要进行一些耗时的操作,会将这个操作放在子线程中进行.在子线程操作完成以后我们可以通过Handler进行发送消息,通知UI进行一些更新操作(具体使用及其原理可以查看And ...
- 【Android 电量优化】JobScheduler 源码分析 ( JobServiceContext 源码分析 | 闭环操作总结 | 用户提交任务 | 广播接收者接受相关广播触发任务执行 )★
文章目录 一.JobServiceContext 引入 二.JobServiceContext 源码分析 三.用户在应用层如何使用 JobScheduler 四.用户提交任务 五.广播接收者监听广播触 ...
- 【Android 电量优化】JobScheduler 相关源码分析 ( JobSchedulerService 源码分析 | Android 源码在线网址推荐 )
文章目录 一.JobScheduler 提交任务 schedule 方法源码分析 二.schedule(JobInfo job, int uId) 方法 三.scheduleAsPackage 方法 ...
- Android AsyncTask源码解读
屡思路 1. 初始 AsyncTask AsyncTask 这个类的声明如下: public abstract class AsyncTask<Params, Progress, Result& ...
最新文章
- 定制iOS 7中的导航栏和状态栏
- 增加 processon 免费文件数
- 五种I/O 模式——阻塞(默认IO模式),非阻塞(常用语管道),I/O多路复用(IO多路复用的应用场景),信号I/O,异步I/O
- 十年沉淀,阿里云发布全球领先的对象存储OSS可用性SLA
- kdj买卖指标公式源码_通达信指标公式源码MACD背离KDJ背离指标
- 程序设计与算法----递归汉诺塔问题
- 小程序:微信小程序开发
- c语言 函数-斐波那契数列,c语言斐波那契数列递归法(示例代码)
- Basler千兆网相机使用相关设置
- CAD二次开发(VB)代码整理
- 关于信息墒与压缩编码基础的学习
- 【PAT】L1-050. 倒数第N个字符串【C语言实现】
- html怎么设置取消隐藏,使用Jquery或Javascript隐藏/取消隐藏html元素
- matlab中numden函数,numden函数 MATLAB里面numden函数有什么用?
- C#查找Excel()重复项
- 基于MATLAB的雷达的杂波模拟器
- 如何看电脑支持最大多少内存条?仅需一个命令
- IPEndPoint 和 EndPoint
- 单片机51实现计算器详细代码能自己运行
- 深入理解Linux虚拟内存管理(二)