昨天写的图片的三级缓存,假设有兴趣,能够去看下,浅谈图片载入的三级缓存原理(一)

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工作机制简介的更多相关文章

  1. Java NIO工作机制简介

    前言 本博客只简单介绍NIO的原理实现和基本工作流程 I/O和NIO的本质区别 NIO将填充和提取缓冲区的I/O操作转移到了操作系统 I/O 以流的方式处理数据,而 NIO 以缓冲区的方式处理数据:I ...

  2. 01_Hive简介及其工作机制

    1.Hive简介 Hive是一个基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一个表.并提供类SQL查询功能, 可以将sql语句转换为MapReduce任务运行.其优点是学习成本低, ...

  3. GVRP 的工作机制和工作模式

    GVRP 简介 GVRP 基于 GARP 的工作机制来维护设备中的 VLAN 动态注册信息,并将该信息向其他设备传播:当设备启动了 GVRP 之后,就能够接收来自其他设备的 VLAN 注册信息,并动态 ...

  4. Nginx 反向代理工作原理简介与配置详解

    Nginx反向代理工作原理简介与配置详解   by:授客  QQ:1033553122   测试环境 CentOS 6.5-x86_64 nginx-1.10.0 下载地址:http://nginx. ...

  5. keepalived之 Keepalived 原理(定义、VRRP 协议、VRRP 工作机制)

    1.Keepalived 定义 Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案,可以利用其来避免单点故障.一个LVS服务会有2台服务器运行Keepalived,一台为主服务器 ...

  6. Android休眠唤醒机制简介(一)【转】

    本文转载自:http://blog.csdn.net/zhaoxiaoqiang10_/article/details/24408129 Android休眠唤醒机制简介(一) ************ ...

  7. Spring学习记录2——简单了解Spring容器工作机制

    简单的了解Spring容器内部工作机制 Spring的AbstractApplicationContext是ApplicationContext的抽象实现类,该抽象类的refresh()方法定义了Sp ...

  8. android 6.0 高通平台sensor 工作机制及流程(原创)

    最近工作上有碰到sensor的相关问题,正好分析下其流程作个笔记. 这个笔记分三个部分: sensor硬件和驱动的工作机制 sensor 上层app如何使用 从驱动到上层app这中间的流程是如何 Se ...

  9. gitlab工作流程简介

    gitlab工作流程简介 新建项目流程 创建/导入项目 可以选择导入github.bitbucket项目,也可以新建空白项目,还可以从SVN导入项目 建议选择private等级 初始化项目 1.本地克 ...

随机推荐

  1. elasticsearch term 查询二:Range Query

    Range Query 将文档与具有一定范围内字词的字段进行匹配. Lucene查询的类型取决于字段类型,对于字符串字段,TermRangeQuery,对于数字/日期字段,查询是NumericRang ...

  2. MySQL5.6 怎样优化慢查询的SQL语句 -- SQL优化

    上篇:MySQL5.6 怎样优化慢查询的SQL语句 -- 慢日志介绍 在实际的日志分析中,通常慢日志的log数量不少,同一时候同样的查询被记录的条数也会非常多.这里就须要怎样从慢日志查询中找到最有问题 ...

  3. Linux源码编译安装MySQL5.7

    目录[-] 一.环境准备: 二.升级系统: 三.做一些准备工作(以下Linux命令均在su到root用户操作): 四.开始编译安装mysql-5.7.9: 一.环境准备: 我尝试过以下环境都是能成功的 ...

  4. JavaScriptl 类数组转换为数组

    slice和Array.form方法,具体见示例代码: <!DOCTYPE html> <html lang="zh"> <head> < ...

  5. java学习路线-Java技术人员之路从0基础到高级

    满满的  全是干货 java基础: 尚学堂 马士兵   个人推荐 历经5年锤练--史上最适合刚開始学习的人入门的Java基础视频   很具体   适合 时间多的看 传智播客java基础班 马士兵线程 ...

  6. Eclipse Mylyn成为顶级项目

    http://www.infoq.com/cn/news/2010/09/eclipse-mylyn/ 作为应用程序的生命周期管理工具,Eclipse Mylyn项目已经被提升为顶级的Eclipse项 ...

  7. SQLServer跨库查询--分布式查询(转载)

    --用openrowset连接远程SQL或插入数据 --如果只是临时访问,可以直接用openrowset --查询示例 select * from openrowset('SQLOLEDB' ,'sq ...

  8. 系统管理员应该知道的 20 条 Linux 命令

    如果您的应用程序不工作,或者您希望在寻找更多信息,这 20 个命令将派上用场. 在这个全新的工具和多样化的开发环境井喷的大环境下,任何开发者和工程师都有必要学习一些基本的系统管理命令.特定的命令和工具 ...

  9. Java 8 Lambda表达式介绍

    Lambda是什么? Lambda是一个匿名函数,我们可以把Lambda理解为是一段可以传递的代码.可以写出简洁.灵活的代码.作为一种更紧凑的代码风格,使java的语言表达能力得到提升. 可以这么说l ...

  10. hdu 4597 Play Game(记忆化搜索)

    题目链接:hdu 4597 Play Game 题目大意:给出两堆牌,仅仅能从最上和最下取,然后两个人轮流取,都依照自己最优的策略.问说第一个人对多的分值. 解题思路:记忆化搜索,状态出来就很水,dp ...