AsyncTask工作机制简介
昨天写的图片的三级缓存,假设有兴趣,能够去看下,浅谈图片载入的三级缓存原理(一)
http://blog.csdn.net/wuyinlei/article/details/50606455
在里面我们下载的时候。採用了AsyncTask异步下载机制,那么今天就来浅谈一下AsycnTask工作机制吧。
首先我们来看下AsyncTask的官方解释
- AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask.
- AsyncTask的设计是环绕主题和Handler一个辅助类,并不构成通用线程框架。异步任务最好应(至多几秒钟。)可用于短期操作。假设您须要保持对长时间运行的线程。强烈建议您使用java.util.concurrent包等提供的各种API作为遗嘱运行人。并ThreadPoolExecutor的FutureTask提供。
(英文不太好,google翻译的哈)
- An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.
- AsyncTask是定义异步任务在后台线程(子线程中)运行的。而结果更新UI在UI线程中,接收三个參数,Params(传入的值)Progress(进度) Result(返回的结果)。有四步onPreExecute(在UI线程中运行,准备操作)doInBackground(子线程中耗时操作)onProgressUpdate (进度更新)onPostExecute(结果返回)
使用方法我就不解释了。能够去官网看下使用方法,这里仅仅说明异步机制。
好了,那我们就来看下源代码运行的操作吧。首先我们从刚開始出发,也就是execute()。
new MyAsync().execute(imageView,url);
AsyncTask的execute()方法:
This method must be invoked on the UI thread.(必须在UI线程中调用)
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
//在这里调用了executeOnExecutor()方法
return executeOnExecutor(sDefaultExecutor, params);
}
来看下executeOnExecutor()方法:
@MainThread(主线程中调用的)
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
//这里有一些异常的推断 。因为代码量多。我就去掉了,在这里我们不考虑异常问题
//在这里首先吧状态给位RUNNING
mStatus = Status.RUNNING;
//运行前的准备工作
onPreExecute();
//这里的params就是我们传入的值,然后赋值给了mWorker,那么我们就要看看这个是什么意思了
mWorker.mParams = params;
//用线程池运行这个future
exec.execute(mFuture);
//终于返回自己
return this;
}
mWorker參数的构造:
/**
* Creates a new asynchronous task. This constructor must be invoked on the UI thread.
*/
public AsyncTask() {
//在构造方法中创建mWorker
mWorker = new WorkerRunnable<Params, Result>() {
//这种方法,一会会用到
public Result call() throws Exception {
mTaskInvoked.set(true);
//设置线程优先级
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
//在这里运行耗时操作,传入我们传入的參数,告诉他要干什么
Result result = doInBackground(mParams);
Binder.flushPendingCommands();
//这个得有值的时候运行
return postResult(result);
}
};
FutureTask中的方法调用:
//然后传递给这个类,把mWorker当做參数传递给FutureTask。
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
//一些异常处理
};
}
那么我们来看下FutureTask这个类做了些什么(接受到mWorker之后):
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
//把mWorker传递给了callable,那么接下来就得看看callable在做什么了
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 {
//在这里把mWorker给了Callable
Callable<V> c = callable;
if (c != null && state == NEW) {
//这里的V就是一个结果的返回类型
V result;
boolean ran;
try {
//事实上就是mWorker.call() 把耗时操作得到的结果给了result
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
//得到result结果,传递给set方法。调用set方法
set(result);
}
} //异常处理
}
set(result) 方法运行:
//Sets the result of this future to the given value unless
* this future has already been set or has been cancelled.
* 把结果也就是future当做參数传递进去。除非这个已经传了或者任务被取消
* /
protected void set(V v) {
if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) {
//在这,把result结果给了outcome。
//传递给outcome
outcome = v;
U.putOrderedInt(this, STATE, NORMAL); // final state
finishCompletion();
}
}
那么接下来就把result给了outcome,我们来看下这个是什么吧:
是一个object对象
private Object outcome;
//在这里把result传递给了x(object对象)
Object x = outcome;
if (s == NORMAL)
//返回future
return (V)x;
if (s >= CANCELLED)
throw new CancellationException();
throw new ExecutionException((Throwable)x);
}
这个时候我们就得到了mFuture对象,我们看看这个干了些什么:
//因为V就是result,在这里把返回的结果传入。然后运行done()方法
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
//异常
};
我们看下mFUture做的什么了
//在这里对mFuture进行了get()方法的回调
public final Result get() throws InterruptedException, ExecutionException {
//在这里又调用了FutureTask里面的方法
return mFuture.get();
FutureTask里面的get()方法:
/**
* @throws CancellationException {@inheritDoc}
*/
public V get() throws InterruptedException, ExecutionException {
int s = state; //得到当前的状态
if (s <= COMPLETING)
s = awaitDone(false, 0L);
//把当前状态传递给report中
return report(s);
}
我们能够看到在get方法中。最后返回了report(s),那就继续跟进去:
/**
* Returns result or throws exception for completed task.
*
* @param s completed state value
*/
@SuppressWarnings("unchecked")
private V report(int s) throws ExecutionException {
Object x = outcome;
if (s == NORMAL)
//直接return回了result 也就是callable.call()方法的结果,或者说是mWorker.call()方法,把DoInBackground()方法返回
return (V)x;
if (s >= CANCELLED)
throw new CancellationException();
throw new ExecutionException((Throwable)x);
}
这里我们就得到了结果result:
//
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
//在这里运行了耗时操作
Result result = doInBackground(mParams);
Binder.flushPendingCommands();
//调用postResult()这种方法,开启了子线程,把结果传了进去
return postResult(result);
}
};
看下postResult(result)方法:
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
//在这里得到的message。然后发出 发送了 MESSAGE_POST_RESULT
Message message =
//发送消息
getHandler().obtainMessage(MESSAGE_POST_RESULT,
//this就是AsyncTask
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
//返回result
return result;
}
AsyncTaskResult(this,result)方法:
@SuppressWarnings({"RawUseOfParameterizedType"})
private static class AsyncTaskResult<Data> {
final AsyncTask mTask;
final Data[] mData;
//这里的data。就是我们返回的结果
AsyncTaskResult(AsyncTask task, Data... data) {
mTask = task;
mData = data;
}
}
我们看下getHandler()方法:
//在这里创建了handler
private static Handler getHandler() {
synchronized (AsyncTask.class) {
if (sHandler == null) {
//在这里new 除了一个handler
sHandler = new InternalHandler();
}
//返回一个handler对象
return sHandler;
}
}
我们看下InternalHandler()方法:
//继承handler,在这里创建了handler
private static class InternalHandler extends Handler {
public InternalHandler() {
super(Looper.getMainLooper());
}
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg) {
AsyncTaskResult<?> result = (AsyncTaskResult<?
>) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
//匹配到MESSAGE_POST_RESULT 。在这里处理结果
//接受耗时操作完毕后传递的消息
// There is only one result
//调用了asynctask的finish()方法,传递的值就是之前耗时操作返回的结果
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
最后调用finish()方法:
private void finish(Result result) {
if (isCancelled()) {
//取消
onCancelled(result);
} else {
//调用了主线程,耗时操作已经完毕。更新UI,在主线程中运行
onPostExecute(result);
}
//在这里把状态改为FINISHED
mStatus = Status.FINISHED;
}
在这里,耗时操作就已经所有完毕了,状态也改为了FINISHED。到此为止。异步完毕。
- AsyncTask工作机制也就这么多了。
当然我们仅仅是考虑了正确工作的状态,也就是请求成功的哈,异常的,取消的,中断的在这里并没有做出解释。
相信大家去看下源代码也是能够晓得原理的。
- 因为小弟才疏学浅,也仅仅能简单的走一下源代码。自己理解有限。有些地方凝视的过于简单,希望大家谅解,假设有独特的,好的解释,希望大神们能够赐教一下。在这里小弟不胜感激。(QQ:1069584784)
AsyncTask工作机制简介的更多相关文章
- Java NIO工作机制简介
前言 本博客只简单介绍NIO的原理实现和基本工作流程 I/O和NIO的本质区别 NIO将填充和提取缓冲区的I/O操作转移到了操作系统 I/O 以流的方式处理数据,而 NIO 以缓冲区的方式处理数据:I ...
- 01_Hive简介及其工作机制
1.Hive简介 Hive是一个基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一个表.并提供类SQL查询功能, 可以将sql语句转换为MapReduce任务运行.其优点是学习成本低, ...
- GVRP 的工作机制和工作模式
GVRP 简介 GVRP 基于 GARP 的工作机制来维护设备中的 VLAN 动态注册信息,并将该信息向其他设备传播:当设备启动了 GVRP 之后,就能够接收来自其他设备的 VLAN 注册信息,并动态 ...
- Nginx 反向代理工作原理简介与配置详解
Nginx反向代理工作原理简介与配置详解 by:授客 QQ:1033553122 测试环境 CentOS 6.5-x86_64 nginx-1.10.0 下载地址:http://nginx. ...
- keepalived之 Keepalived 原理(定义、VRRP 协议、VRRP 工作机制)
1.Keepalived 定义 Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案,可以利用其来避免单点故障.一个LVS服务会有2台服务器运行Keepalived,一台为主服务器 ...
- Android休眠唤醒机制简介(一)【转】
本文转载自:http://blog.csdn.net/zhaoxiaoqiang10_/article/details/24408129 Android休眠唤醒机制简介(一) ************ ...
- Spring学习记录2——简单了解Spring容器工作机制
简单的了解Spring容器内部工作机制 Spring的AbstractApplicationContext是ApplicationContext的抽象实现类,该抽象类的refresh()方法定义了Sp ...
- android 6.0 高通平台sensor 工作机制及流程(原创)
最近工作上有碰到sensor的相关问题,正好分析下其流程作个笔记. 这个笔记分三个部分: sensor硬件和驱动的工作机制 sensor 上层app如何使用 从驱动到上层app这中间的流程是如何 Se ...
- gitlab工作流程简介
gitlab工作流程简介 新建项目流程 创建/导入项目 可以选择导入github.bitbucket项目,也可以新建空白项目,还可以从SVN导入项目 建议选择private等级 初始化项目 1.本地克 ...
随机推荐
- Chrome 37 Beta: 使用Windows的DirectWrite和支持<dialog>元素
今天的Chrome Beta 发布版包含了许多新的开发者特性.这些特性帮助你制作更丰富的.更迅速的和更引人入胜的网页内容以及应用程序,尤其是移动设备上.除非特别指出,否则下面描述的变化对Android ...
- hdu5289 Assignment (区间查询最大值最小值,st算法...)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5289 题意:给定长度为n的序列a和一个整数K,找出最大值和最小值的差值小于K的区间.输出满足条件的区间的个 ...
- React Router V4发布
React Router V4 正式版发布,该版本相较于前面三个版本有根本性变化,遵循 Just Component 的 API 设计理念. 本次升级的主要变更有: 声明式 Declarative 可 ...
- Mycat探索之旅(4)----Mycat的自增长主键和返回生成主键ID的实现
说明:MyCAT自增长主键和返回生成主键ID的实现 1) mysql本身对非自增长主键,使用last_insert_id()是不会返回结果的,只会返回0:这里做一个简单的测试 创建测试表 ------ ...
- java泛型 7 泛型的基本介绍和使用
现在开始深入学习Java的泛型了,以前一直只是在集合中简单的使用泛型,根本就不明白泛型的原理和作用.泛型在java中,是一个十分重要的特性,所以要好好的研究下. 一.泛型的基本概念 泛型的定义:泛型是 ...
- Timus Online Judge 1057. Amount of Degrees(数位dp)
1057. Amount of Degrees Time limit: 1.0 second Memory limit: 64 MB Create a code to determine the am ...
- Linux下中断程序导致写文件失败的分析
案例: 一个普通linux C程序,执行期间会进行多次printf操作,利用bash脚本重定向功能,将stdout重定向到一个另一个文件中去.在运行途中用ctrl+C终止程序,发现定向文件始终为空,即 ...
- java的IO操作:字节流与字符流操作
流的概念 程序中的输入输出都是以流形式,流中保存的实际上都是字节文件. 字节流与字符流 字节流的操作: 1)输入:inputStream, 2)输出:outPutStream; 字符流的操作: 1)输 ...
- 在Gridview中输入小数时报对于int32 太大或太小
使用Datagridview绑定Access数据库,对于数字类型的数据输入小数后报以下错误: 根据错误判断应该是自动检测该栏位应该输入int32类型的数值.我在数据库中定义了保留4位小数,为什么还被转 ...
- 非等高cell实战--实现微博页面
代码地址如下:http://www.demodashi.com/demo/11639.html 前言 学习过UITableView.AutoLayout以及MVC的相关知识,接下来通过一个微博页面实战 ...