一说到AsyncTask,大家就会说 ,他是系统提供给我的用于执行异步任务的工具类。比Handler好用只需要重写方法,每个Asynchronous对象只能执行1次。但是他必须要放在主线程里创建。为什么呢?这都是为什么呢?我们就来对这些疑惑一探究竟:
打开这个类,我喜欢只有除去一些注释只有250多行:
二话不说,先看他的构造吧:
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
return doInBackground(mParams);//调用了doInBackground
}
};//构建了一个mWorkà WorkerRunnable是具有prams参数的一个抽象类,实现了Callable接口。
mFuture = new FutureTask<Result>(mWorker) {//用mWorker创建了FutureTask
@Override// FutureTask
(Runnable runnable, V result)
//FutureTask通过一个Runnable/Callable构造,一旦运行完成通过get();返回一个Result
protected void done() {
Message message;
Result result = null;
try {
result = get();//获得mWork返回的Result
} 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));
// sHandler是自己的Handler:obtainMessage:通过what,obj获得msg;
//实际调用: Message.obtain(this, what, obj);得到1个MSg
message.sendToTarget();//target.send(msg)发送了一个消息给自觉封装好的Handler
return;
} catch (Throwable t) {
throw new RuntimeException("An error occured while executing "
+ "doInBackground()", t);
}
message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(AsyncTask.this, result));
message.sendToTarget();
}
};
}
这时调用了HandleMessage()方法,下面是那个Handler的具体代码:
private static class InternalHandler extends Handler {
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override//看到了吧,我们要重写的几个方法。他们现在都是空实现。
public void handleMessage(Message msg) {
AsyncTaskResult result = (AsyncTaskResult) msg.obj;//取得消息里的Result
switch (msg.what) {
case MESSAGE_POST_RESULT://当消息是完成时的操作
// There is only one result
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;
}
}
}
这里涉及到一个AsyncTaskResult result和:
private static class AsyncTaskResult<Data> {//创建分派消息时,将Result封装为AsyncTaskResult
final AsyncTask mTask;//封装1个异步任务,创建消息时this
final Data[] mData;//我们创建消息时mData:为Result
AsyncTaskResult(AsyncTask task, Data... data) {
mTask = task;
mData = data;
}
}
哪为什么要在Ui线程实例化呢,:
因为他的本质还是Handler,Handler对象与当前线程关联,也就说,我们想通过异步分离UI和后台处理,当然要在Ui实例化。
为什么又只能执行1次呢:
我们看,通过代码的结构:我们要通过execute执行(为什么?)来传递我们要执行的参数:
他内部定义了一个状态并初始化为PENGDING:
private volatile Status mStatus = Status.PENDING;
public enum Status {PENDING, RUNNING, FINISHED, }
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
if (mStatus != Status.PENDING) {
switch (mStatus) {
case RUNNING:
throw new IllegalStateException("Cannot execute task:"
+ " the task is already running.");
case FINISHED:
throw new IllegalStateException("Cannot execute task:"
+ " the task has already been executed "
+ "(a task can be executed only once)");
}
}
mStatus = Status.RUNNING;//只能在这里修改1次,这就是执行1次的原因.
onPreExecute();//如果定义了onPreExecute(),则执行,否则空实现;
mWorker.mParams = params;//初始化mWorker的参数
sExecutor.execute(mFuture);//这是执行FutureTask的方式。回到了我上面的讲解。
return this;
}
这里也顺便讲一下Progress的更新吧:
protected final void publishProgress(Progress... values) {
sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
这下,你是不是明白呢!
分享到:
相关推荐
代码为博客的示例代码,有问题请博客中留言:http://blog.csdn.net/lmj623565791/article/details/38614699
本文先简要介绍AsyncTask的用法,然后分析具体实现。 基本用法 AsyncTask是一个抽象类,我们需要创建子类去继承它,并且重写一些方法。AsyncTask接受三个泛型参数: Params: 指定传给任务执行时的参数的类型 ...
异步任务Asynctask源码与反编译对比,来分析源代码
Android中AsyncTak的使用与源码分析 Android AsyncTask 完全解析,带你从源码的角度彻底理解 Android 异步消息处理机制完全解析,带你从源码角度彻底理解 Android 异步消息处理机制 让你深入理解 Looper、...
主要介绍了Android AsyncTask实现机制详细介绍及实例代码的相关资料,这里附有示例代码,帮助大家学习理解,需要的朋友可以参考下
我们都知道,Android UI是线程不安全的,如果想要在子线程里进行UI操作,就需要借助Android的异步消息处理机制。...不过今天我还是准备从AsyncTask的基本用法开始讲起,然后我们再来一起分析下AsyncTask源码,看看它
AsyncTask源码分析 插件化技术 自定义控件 事件分发机制 ANR问题 Art和Dalvik的区别 Android关于OOM的解决方案 Fragment Activity&Fragment SurfaceView Android几种进程 APP启动过程 Activity启动流程以及界面展示...
AsyncTask源码分析 插件化技术 自定义控件 事件分发机制 ANR问题 Art和Dalvik的区别 Android关于OOM的解决方案 Fragment Activity&Fragment SurfaceView Android几种进程 APP启动过程 Activity启动流程以及界面展示...
ListView源码分析 VideoView源码分析 View绘制过程详解 网络部分 HttpURLConnection详解 HttpURLConnection与HttpClient volley-retrofit-okhttp之我们该如何选择网路框架 Volley源码分析 Retrofit详解(上) Retrofit...
主要介绍了Android中AsyncTask与handler用法,以实例形式较为详细的分析了Android中AsyncTask与handler的功能、用法与相关注意事项,并附带完整实例源码供读者下载,需要的朋友可以参考下
主要介绍了Android通过Handler与AsyncTask两种方式动态更新ListView的方法,结合实例形式分析了ListView动态更新的常用技巧,并附上完整实例源码供读者下载,需要的朋友可以参考下
Android核心分析28篇,强烈推荐android初学者,android进阶者看看这个系列教程 Android应用开发者指南:性能优化 android开发教程合集(推荐新手看下这一季教程) 新手入门 会员贡献电子图书整理(内含PDF下载) ...
本书是一本Android进阶类书籍,采用理论、源码和实践相结合的方式来阐述高水准的Android应用开发要点。本书从三个方面来组织内容。第一,介绍Android开发者不容易掌握的一些知识点;第二,结合Android源代码和应用层...
《Android开发艺术探索》是一本Android进阶类书籍,采用理论、源码和实践相结合的方式来阐述高水准的Android应用开发要点。《Android开发艺术探索》从三个方面来组织内容。第一,介绍Android开发者不容易掌握的一些...
它提供了Params, Progress和 Result三个泛型参数,在下面会仔细分析这三个泛型参数的具体含义。 AsyncTask提供了四个核心方法 onPreExecute() 此方法在主线程中执行,在异步任务执行之前,此方法会被调用,一般用于...
介绍了AsyncTask的使用,及源码分析。线程池,有返回值的线程。
我们知道,多线程是Android开发中必现的场景,很多原生API和开源项目都有多线程的内容,这里简单总结和探讨一下常见的多线程切换方式。 我们先回顾一下Java多线程的几个基础内容,然后再分析总结一些经典代码中对于...