AsyncTask

new AsyncTask<String,String,String>(){
// 运行在主线程中,做预备工作
onPreExecute(){ }
// 运行在子线程中,做耗时操作
String doingBackGround(String s){ }
// 运行在主线程中,耗时操作完成,更新UI
onPostExecute(String s){ } }.execute(String);

AsyncTask的execute方法

public final AsyncTask<Params, Progress, Result> execute(Params... params) {
... mStatus = Status.RUNNING;
// 在主线程中执行准备操作
onPreExecute();
// 把params参数赋值给mWorker
mWorker.mParams = params;
// 用线程池执行mFuture
sExecutor.execute(mFuture); // 在AsyncTask构造方法中创建了mWorker
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
...
}
}; mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
...
}
};
}
// 把mWorker传递给FutureTask,callable指的就是mWorker
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
sync = new Sync(callable);
}
// 把mWorker传递给Sync,callable指的是mWorker
Sync(Callable<V> callable) {
this.callable = callable;
}

线程池执行FutureTask,就是执行FutureTask的run方法,代码如下:

    public void run() {
// 转调
sync.innerRun();
} void innerRun() {
if (!compareAndSetState(READY, RUNNING))
return; runner = Thread.currentThread();
if (getState() == RUNNING) { // recheck after setting thread
V result;
try {
// 就是调用了mWorker.call方法
// 把耗时操作得到的结果赋值给result
result = callable.call();
} catch (Throwable ex) {
setException(ex);
return;
}
// 转调了sync.innerSet(v);
set(result);
} else {
releaseShared(0); // cancel
}
} mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
// 执行耗时操作 在子线程中执行
return doInBackground(mParams);
}
}; protected void set(V v) {
// 转调
sync.innerSet(v);
} void innerSet(V v) {
for (;;) {
int s = getState();
if (s == RAN)
return;
if (s == CANCELLED) {
// aggressively release to set runner to null,
// in case we are racing with a cancel request
// that will try to interrupt runner
releaseShared(0);
return;
}
if (compareAndSetState(s, RAN)) {
result = v;
releaseShared(0);
// 调用了FutureTask的抽象方法
done();
return;
}
}
} mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
Message message;
Result result = null; try {
// 转调了sync.innerGet()
result = get();
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occured while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,
new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));
message.sendToTarget();
return;
} catch (Throwable t) {
throw new RuntimeException("An error occured while executing "
+ "doInBackground()", t);
}
// 发送了一个Message
message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(AsyncTask.this, result));
message.sendToTarget();
}
}; public V get() throws InterruptedException, ExecutionException {
// 转调
return sync.innerGet();
} V innerGet() throws InterruptedException, ExecutionException {
acquireSharedInterruptibly(0);
if (getState() == CANCELLED)
throw new CancellationException();
if (exception != null)
throw new ExecutionException(exception);
// 把之前doinBackground方法的结果返回
return result;
}

在AsyncTask的成员变量,创建了InternalHandler

private static class InternalHandler extends Handler {
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg) {
AsyncTaskResult result = (AsyncTaskResult) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
// There is only one result
// 结束耗时操作完成后的消息
// 调用了AsyncTask的finish方法传递的result.mData[0]就是之前
// 耗时操作返回来的结果
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
case MESSAGE_POST_CANCEL:
result.mTask.onCancelled();
break;
}
}
}
private static class AsyncTaskResult<Data> {
final AsyncTask mTask;
final Data[] mData;
// data 是返回的结果
AsyncTaskResult(AsyncTask task, Data... data) {
mTask = task;
mData = data;
}
} private void finish(Result result) {
if (isCancelled()) result = null;
// 耗时操作完成,更新UI,执行在主线程
onPostExecute(result);
mStatus = Status.FINISHED;
}

源码篇——AsyncTask机制的更多相关文章

  1. 鸿蒙内核源码分析(调度机制篇) | 任务是如何被调度执行的 | 百篇博客分析OpenHarmony源码 | v7.07

    百篇博客系列篇.本篇为: v07.xx 鸿蒙内核源码分析(调度机制篇) | 任务是如何被调度执行的 | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调 ...

  2. 源码篇:SDWebImage

    攀登,一步一个脚印,方能知其乐 源码篇:SDWebImage 源码来源:https://github.com/rs/SDWebImage 版本: 3.7 SDWebImage是一个开源的第三方库,它提 ...

  3. springMVC源码分析--异常处理机制HandlerExceptionResolver执行原理(二)

    上一篇博客springMVC源码分析--异常处理机制HandlerExceptionResolver简单示例(一)中我们简单地实现了一个异常处理实例,接下来我们要介绍一下HandlerExceptio ...

  4. Dubbo 源码分析 - SPI 机制

    1.简介 SPI 全称为 Service Provider Interface,是 Java 提供的一种服务发现机制.SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加 ...

  5. MyBatis 源码分析 - 插件机制

    1.简介 一般情况下,开源框架都会提供插件或其他形式的拓展点,供开发者自行拓展.这样的好处是显而易见的,一是增加了框架的灵活性.二是开发者可以结合实际需求,对框架进行拓展,使其能够更好的工作.以 My ...

  6. spring-boot-2.0.3启动源码篇二 - run方法(一)之SpringApplicationRunListener

    前言 Springboot启动源码系列还只写了一篇,已经过去一周,又到了每周一更的时间了(是不是很熟悉?),大家有没有很期待了?我会尽量保证启动源码系列每周一更,争取不让大家每周的期望落空.一周之中可 ...

  7. spring-boot-2.0.3启动源码篇 - 阶段总结

    前言 开心一刻 朋友喜欢去按摩,第一次推门进来的是一个学生美眉,感觉还不错:后来经常去,有时是护士,有时是空姐,有时候是教师.昨天晚上推门进去的是一个女警察,长得贼好看,身材也很好,朋友嗷的一声就扑上 ...

  8. MySQL Master High Available 源码篇

    https://m.aliyun.com/yunqi/users/1287368569594542/articles https://yq.aliyun.com/articles/59233 MySQ ...

  9. MyBatis 源码篇-整体架构

    MyBatis 的整体架构分为三层, 分别是基础支持层.核心处理层和接口层,如下图所示. 基础支持层 反射模块 该模块对 Java 原生的反射进行了良好的封装,提供了更加简洁易用的 API ,方便上层 ...

随机推荐

  1. [LeetCode] Circular Array Loop 环形数组循环

    You are given an array of positive and negative integers. If a number n at an index is positive, the ...

  2. [LeetCode] Add One Row to Tree 二叉树中增加一行

    Given the root of a binary tree, then value v and depth d, you need to add a row of nodes with value ...

  3. POJ2135:Farm Tour

    题意:给定一个无向图,从1走到n再从n走回1,每个边只能走一遍,求最短路 题解:可以定义一个源点s,和一个汇点t s和1相连容量为2,费用为0, t和n相连容量为2,费用为0 然后所用的边的容量都定为 ...

  4. CSAPP-链接

    主要任务: 1.符号解析 在声明变量和函数之后,所有的符号声明都被保存到符号表. 而符号解析阶段会给每个符号一个定义. 2.重定位: 把每个符号的定义与一个内存位置关联起来,然后修改所有对这些符号的引 ...

  5. 2015 多校联赛 ——HDU5372(树状数组)

    Sample Input 3 0 0 0 3 0 1 5 0 1 0 0 1 1 0 1 0 0   Sample Output Case #1: 0 0 0 Case #2: 0 1 0 2 有0, ...

  6. Luogu1613 跑路

    题目描述 小A的工作不仅繁琐,更有苛刻的规定,要求小A每天早上在6:00之前到达公司,否则这个月工资清零.可是小A偏偏又有赖床的坏毛病.于是为了保住自己的工资,小A买了一个十分牛B的空间跑路器,每秒钟 ...

  7. bzoj3198[Sdoi2013]spring 容斥+hash

    3198: [Sdoi2013]spring Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1143  Solved: 366[Submit][Sta ...

  8. 树莓派超声波测距+蜂鸣器(c语言)

    前边我们已经详细的讲解了树莓派控制超声波模块测距(http://www.cnblogs.com/yuemo/p/8888342.html)和超声波控制蜂鸣器模块发声(http://www.cnblog ...

  9. VM11 CentOS6.7 i386 安装 oracle 11g r2

    CentOS 6.7 i386:最小桌面版本--中文1.网络配置 ifup eht0 vim /etc/sysconfig/network-scripts/ifcfg-eth0 修改:NBOOT=ye ...

  10. javascript requestAnimationFarme

    今天看到一篇很好的文章推荐一下:原文地址:http://www.zhangxinxu.com/wordpress/?p=3695 CSS3动画那么强,requestAnimationFrame还有毛线 ...