AsyncTask2
参考:
AsyncTask - 简书
http://www.jianshu.com/p/3b839d7a3fcf
前言
在android应用开发过程中,我们需要是时刻注意保证应用程序的稳定和UI操作响应及时,不稳定或响应不及时会带来不好的用户体验。
为何要引入AsyncTask?
在Android程序开始运行的时候会单独启动一个进程,默认情况下所有这个程序操作都在这个进程中进行。一个Android程序默认情况下只有一个进程,但一个进程中可以有多个线程。
在这些线程中,有一个线程叫做UI线程(也叫Main Thread),除了UI线程外的线程都叫子线程(Worker Thread)。UI线程主要负责控制UI界面的显示、更新、交互等。因此,UI线程中的操作延迟越短越好(流畅)。把一些耗时的操作(网络请求、数据库操作、逻辑计算等)放到单独的线程,可以避免主线程阻塞。
Android给我们提供了一种轻量级的异步任务类AsyncTask。该类中实现异步操作,并提供接口反馈当前异步执行结果及进度,这些接口中有直接运行在主线程中的(如 onPostExecute,onPreExecute等)。
API
百度翻译:
AsyncTask使适当的和易用的UI线程。这个类可以执行后台操作,并在用户界面上发布结果,而不必处理线程和/或处理程序。
AsyncTask的设计是围绕线程和处理器的一个辅助类,并不构成一个通用的线程框架。asynctasks应该用于短作业(最多。几秒钟)如果你需要保持线程运行很长一段时间,我们强烈建议您使用不同的java.util.concurrent包如执行API提供的,线程池和futuretask。
异步任务被定义为一个在后台线程上运行的运算,其结果是在用户界面上发布的。一个异步任务是由3的泛型类型定义为参数,过程和结果,和4个步骤,称为onpreexecute,doInBackground,onProgressUpdate和onpostexecute。
使用(API):
AsyncTask must be subclassed to be used. The subclass will override at least one method (
), and most often will override a second one (
.)
AsyncTask必须被子类继承使用。子类至少重写一个方法(doInBackground(Params...)),和最经常会重写第二个方法(onPostExecute(result))
AsyncTask的泛型
一个异步任务使用的三种类型如下:
1.Params,the type of the parameters sent to the task upon execution.(参数的类型发送到任务执行时。)
网络访问时可以做String来传URI。
2.Progress,the type of the progress units published during the background computation.(后台计算过程中的进度单元类型。)
进度条参数。onProgressUpdate方法可以用这个参数来更新进度条。
3.Result,the type of the result of the background computation.(后台运行的结果类型。)
Result参数可以存储从网络上面获取的数据。
doInBackground将result参数传递给onpostexecute,onpostexecute方法可以用这个参数来更新界面。
Not all types are always used by an asynchronous task. To mark a type as unused, simply use the typeVoid:(不是所有的参数都需要,不用时可以返回void类型)
源码:
AsyncTask内部逻辑主要有二部分:
1.与主线程交互,它内部实例化一个静态的自定义类InternalHandler,这个类是继承Handler的,在这个自定义类中绑定了一个叫做AsyncTaskResult的对象,每次子线程需要通知主线程,就调用sendToTarget发消息给handle,然后在handle的handleMessage中AsyncTaskResult根据消息的类型不同(如MESSAGE_POST_PROGRESS会更新进度条,MESSAGE_POST_CANCEL取消任务)而做这些操作都是在UI线程进行的。意味着,从子线程一旦需要和UI线程交互,内部自动调用了handler对象把消息放在主线程。(onProgressUpdate用于更新界面任务进度)
2.AsyncTask内部调用,虽然可以新建多个AsyncTask的子类实例,但是AsyncTask内部Handler和ThreadPoolExecutor都是static,这么定义是进程范围内共享的,所以AsyncTask控制着的进程范围内所有的子类实例,且该类的所有实例都共用一个线程池(serialExecutor和THREAD_POOL_EXECUTOR)和 另一个线程池Handler(InternalHandler)。
从代码可以看出,默认核心线程池的大小CORE_POOL_SIZE是根据Runtime.getRuntime().availableProcessors()获取设备的核数(比如你手机双核返回2),通常线程池的大小是默认期望的并发数。如:默认核心线程池大小5。意味着,如果线程池数量小于5,这时候新添加一个异步任务则会新建一个线程,如果数量大于等于5,这时候新建的异步任务会被放入缓存队列中等待。限制APP内AsyncTask并发的线程是有必要的。同时运行任务多,线程多,会导致短时间内手机内存被占完!
事实上,从android 3.0开始,每次新建异步任务的时候AsyncTask内部默认规则是按提交的先后顺序每次只运行一个异步任务。当然你也可以自己指定自己的线程池。
AsyncTask的工作原理
1.从他的execute方法开始分析,会调用executeOnExecutor();其中AsyncTask的onPreExecute方法是最先执行的,然后线程池开始执行。
2.从代码看,sDefaultExecutor实际上是一个串行的线程池,一个进程中所有的AsyncTask全部都在这个线程池中执行。从SerialExecutor的实现分析AsyncTask的排队执行的过程。
首先系统会把AsyncTask的参数封装为FutureTask对象,FutureTask是一个并发类,在这里它充当了Runnable的作用。
接着这个FutureTask会交给SerialExecutor的execute方法处理,execute方法会先把FutureTask对象插入到任务队列mTask中,如果这时没有正在活动的任务,那么就会调用SeriaExecutor的scheduleNext()类执行下个任务。同一个AsyncTask任务执行完后,AsyncTask会继续执行其他任务知道所有任务都被执行完,从这一点可以看出,默认情况下AsyncTask是串行执行的。
3.不行看得想吐了!W~u ~a~a.....
Note:
1.由于Handler需要和主线程交互,而Handler又是内置于AsyncTask中,所有AsyncTask的创建必须在主线程。
2.AsyncTaskResult的doInBackground(Params)方法执行异步任务运行在子线程中,其他方法运行在主线程中,可以操作UI组件。
3.不要手动的去调用AsyncTask的onPreExecute, doInBackground, publishProgress, onProgressUpdate, onPostExecute方法,这些都是由android系统自动调用的。
4.一个AsyncTask任务只能被执行一次。
5.运行中可以随时调用cancel(boolean)方法取消任务,如果成功调用isCancel()会返回true,并不会执行onPostExecute(),取而代之的是调用onCancelled()。从源码看,如果这个任务已经执行了这个时候调用cancel是不会真正的把task结束,而是继续执行,只不过改变的是执行之后的回调方法的onPostExecute还是onCancelled.
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}
sHandler进度消息发送,
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
此处处理消息,系统调用重写的onProgressUpdate来更新进度。
AsyncTask2的更多相关文章
- 安卓开发--AsyncTask2
package com.cnn.imageasyncdemo01; import android.app.Activity; import android.content.Intent; import ...
- Promise的前世今生和妙用技巧
浏览器事件模型和回调机制 JavaScript作为单线程运行于浏览器之中,这是每本JavaScript教科书中都会被提到的.同时出于对UI线程操作的安全性考虑,JavaScript和UI线程也处于同一 ...
- Android 结合实例学会AsyncTask的用法
AsyncTask执行时经过四个步骤,执行四个方法: 1.onPreExecute(),运行在UI线程,可以设置或修改UI控件,如显示一个进度条 2.doInBackground,运行在后台线程,不可 ...
- Android 结合实例学会AsyncTask的使用方法
AsyncTask运行时经过四个步骤,运行四个方法: 1.onPreExecute(),执行在UI线程,能够设置或改动UI控件,如显示一个进度条 2.doInB ...
- 使用Promise
Promise所要解决的问题:回调地狱 asyncTask1(data, function (data1){ asyncTask2(data1, function (data2){ asyncTask ...
- Spring boot 使用WebAsyncTask处理异步任务
上文介绍了基于 @Async 注解的 异步调用编程,本文将继续引入 Spring Boot 的 WebAsyncTask 进行更灵活异步任务处理,包括 异步回调,超时处理 和 异常处理. 正文 1. ...
- SpringBoot中Async异步方法和定时任务介绍
1.功能说明 Spring提供了Async注解来实现方法的异步调用. 即当调用Async标识的方法时,调用线程不会等待被调用方法执行完成即返回继续执行以下操作,而被调用的方法则会启动一个独立线程来执行 ...
- Android -- AsyncTask 使用和缺陷
一.AsyncTask的基本用法 由于AsyncTask是一个抽象类,所以如果我们想使用它,就必须要创建一个子类去继承它.在继承时我们可以为AsyncTask类指定三个泛型参数,这三个参数的用途如下: ...
随机推荐
- 跨域资源共享(CORS)-漏洞整理
绕过方法整理 绕过 - 仅对域名校验 #POC #"Access-Control-Allow-Origin: https://xx.co & Access-Control-Allow ...
- NYOJ 654喜欢玩warcraft的ltl(01背包/常数级优化)
传送门 Description ltl 非常喜欢玩warcraft,因为warcraft十分讲究团队整体实力,而他自己现在也为升级而不拖累团队而努力. 他现在有很多个地点来选择去刷怪升级,但是在每一个 ...
- Orcle获取当前时间加小时
如下是oracle 获取当前数据库时间加2个小时 select to_date(TO_CHAR (SYSDATE, 'yyyy-mm-dd hh24:mi:ss'),'yyyy-mm-dd hh24: ...
- Java8默认方法
Java8引入的接口默认方法实现一个新的概念.此功能是为了向后兼容性增加,使旧接口可用于利用JAVA8. lambda表达式的能力,例如,列表或集合接口不具备forEach方法声明.从而增加了这样的方 ...
- php和java的优势
现在市场上的电子商务软件基本上可归结为两大阵营,即PHP阵营和Java阵营.但对接触电子商务不久的用户来说,看到的往往只是它们的表相,只是明显的价格差异,却很难看出它们之间的实际差异.下面我们就为大家 ...
- mysql 5.7 创建函数报错,This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creat
今天用命令创建函数, 报错 This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration ...
- noip2018考后反思之爆0
今年又被Han老师鞭尸了TAT noip普及组比齐同学考的都差,正在准备退役Orz 哎,算了,该放题解还是要放的:( 普及第一题我觉得没有放的必要还是放一下 Code: #include<ios ...
- Spring学习笔记(14)——SpEL
是什么 Spring表达式语言全称为"Spring Expression Language",缩写为"SpEL",类似于Struts2x中使用的OGNL表达式语 ...
- WEEX-EROS开发小笔记
本文是作者之前刚接触移动端跨平台开发,使用weex-eros开发项目平日里记下来的一些笔记,分享出来方便为新手解惑,weex-eros是weex的一套解决方法,使用vue语法糖,对于前端开发者来说可以 ...
- ubuntu开发c/c++帮助文档
1.C语言库函数基本的帮助文档 sudo apt-get install manpages sudo apt-get install manpages-de sudo apt-get install ...