linux异步实现原理,Android异步处理四:AsyncTask的实现原理

分析:

在分析实现流程之前,我们先了解一下AsyncTask有哪些成员变量。

privatestaticfinalintCORE_POOL_SIZE =5;//5个核心工作线程

privatestaticfinalintMAXIMUM_POOL_SIZE =128;//最多128个工作线程

privatestaticfinalintKEEP_ALIVE =1;//空闲线程的超时时间为1秒

privatestaticfinalBlockingQueue sWorkQueue =

newLinkedBlockingQueue(10);//等待队列

privatestaticfinalThreadPoolExecutorsExecutor =newThreadPoolExecutor(CORE_POOL_SIZE,

MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue,sThreadFactory);//线程池是静态变量,所有的异步任务都会放到这个线程池的工作线程内执行。

回到例子中,点击按钮之后会新建一个GetCSDNLogoTask对象:

GetCSDNLogoTask task =newGetCSDNLogoTask();

此时会调用父类AsyncTask的构造函数:

AsyncTask.java

publicAsyncTask() {

mWorker =newWorkerRunnable() {

publicResult call()throwsException {

Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

returndoInBackground(mParams);

}

};

mFuture =newFutureTask(mWorker) {

@Override

protectedvoiddone() {

Message message;

Result result =null;

try{

result = get();

}catch(InterruptedException e) {

Android.util.Log.w(LOG_TAG, e);

}catch(ExecutionException e) {

thrownewRuntimeException("An error occured while executing doInBackground()",

e.getCause());

}catch(CancellationException e) {

message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,

newAsyncTaskResult(AsyncTask.this, (Result[])null));

message.sendToTarget();//取消任务,发送MESSAGE_POST_CANCEL消息

return;

}catch(Throwable t) {

thrownewRuntimeException("An error occured while executing "

+"doInBackground()", t);

}

message = sHandler.obtainMessage(MESSAGE_POST_RESULT,

newAsyncTaskResult(AsyncTask.this, result));//完成任务,发送MESSAGE_POST_RESULT消息并传递result对象

message.sendToTarget();

}

};

}

WorkerRunnable类实现了callable接口的call()方法,该函数会调用我们在AsyncTask子类中实现的doInBackground(mParams)方法,由此可见,WorkerRunnable封装了我们要执行的异步任务。FutureTask中的protected void done() {}方法实现了异步任务状态改变后的操作。当异步任务被取消,会向UI线程传递MESSAGE_POST_CANCEL消息,当任务成功执行,会向UI线程传递MESSAGE_POST_RESULT消息,并把执行结果传递到UI线程。

由此可知,AsyncTask在构造的时候已经定义好要异步执行的方法doInBackground(mParams)和任务状态变化后的操作(包括失败和成功)。

当创建完GetCSDNLogoTask对象后,执行

task.execute("http://www.linuxidc.com/pic/logo.gif");

此时会调用AsyncTask的execute(Params...params)方法

AsyncTask.java

publicfinalAsyncTask execute(Params... params) {

if(mStatus != Status.PENDING) {

switch(mStatus) {

caseRUNNING:

thrownewIllegalStateException("Cannot execute task:"

+" the taskis already running.");

caseFINISHED:

thrownewIllegalStateException("Cannot execute task:"

+" the taskhas already been executed "

+"(a task canbe executed only once)");

}

}

mStatus = Status.RUNNING;

onPreExecute();//运行在ui线程,在提交任务到线程池之前执行

mWorker.mParams = params;

sExecutor.execute(mFuture);//提交任务到线程池

returnthis;

}

当任务正在执行或者已经完成,会抛出IllegalStateException,由此可知我们不能够重复调用execute(Params...params)方法。在提交任务到线程池之前,调用了onPreExecute()方法。然后才执行sExecutor.execute(mFuture)是任务提交到线程池。

前面我们说到,当任务的状态发生改变时(1、执行成功2、取消执行3、进度更新),工作线程会向UI线程的Handler传递消息。在《Android异步处理三:Handler+Looper+MessageQueue深入详解》一文中我们提到,Handler要处理其他线程传递过来的消息。在AsyncTask中,InternalHandler是在UI线程上创建的,它接收来自工作线程的消息,实现代码如下:

AsyncTask.java

privatestaticclassInternalHandlerextendsHandler {

@SuppressWarnings({"unchecked","RawUseOfParameterizedType"})

@Override

publicvoidhandleMessage(Message msg) {

AsyncTaskResult result =(AsyncTaskResult) msg.obj;

switch(msg.what) {

caseMESSAGE_POST_RESULT:

// There is onlyone result

result.mTask.finish(result.mData[0]);//执行任务成功

break;

caseMESSAGE_POST_PROGRESS:

result.mTask.onProgressUpdate(result.mData);//进度更新

break;

caseMESSAGE_POST_CANCEL:

result.mTask.onCancelled();//取消任务

break;

}

}

}

当接收到消息之后,AsyncTask会调用自身相应的回调方法。

总结:

1、 AsyncTask的本质是一个静态的线程池,AsyncTask派生出的子类可以实现不同的异步任务,这些任务都是提交到静态的线程池中执行。

2、线程池中的工作线程执行doInBackground(mParams)方法执行异步任务

3、当任务状态改变之后,工作线程会向UI线程发送消息,AsyncTask内部的InternalHandler响应这些消息,并调用相关的回调函数0b1331709591d260c1c78e86d0c51c18.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/505680.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql5.7 for linux7,大道浮屠诀---mysql5.7.28 for linux安装

环境:redhat6.5安装RMP包的具体操作如下:1、如有mariadb,先卸载rpm -qa |grep mariadbrpm -qa |grep mysql*rpm -e --nodeps xxxxxx (卸载查询到的rpm包)2、安装新的mysql5.7.28,解压安装包tar -xvf mysql-5.7.28-1.el6.x86_64.rpm-bundle.t…

一维数组kmeans聚类c语言,一维数组的 K-Means 聚类算法理解

刚看了这个算法,理解如下,放在这里,备忘,如有错误的地方,请指出,谢谢需要做聚类的数组我们称之为【源数组】需要一个分组个数K变量来标记需要分多少个组,这个数组我们称之为【聚类中心数组】及一…

c语言根据图片轮廓图,c语言通过opencv实现轮廓处理与切割

c语言通过opencv实现轮廓处理与切割发布时间:2020-10-14 11:00:33来源:脚本之家阅读:89作者:Farmwang注意在寻找轮廓时要选择中寻找外层轮廓RETR_EXTERNAL#include "opencv/cv.h"#include "opencv/highgui.h"…

android 指定语言的资源,Android国际化多语言切换

最近工作中突然要求要项目进行国际化,之前没遇到过。但是也很简单呀,只需要把添加一个相应语言的的strings.xml的资源文件就好了,不是吗?这样只要切换系统语言就能切换app的文字语言了。但是由此引发了一个稍微深入一点的问题&…

Android 抖音爱心动画,Android实现抖音心形函数

刷抖音的时候,无意间刷到 心形函数的动画,觉得很有意思, 就简单的用Android的方式实现了一下.心形函数公式公式 :心形公式X的取值范围:[-1.81,1.81],该取值范围是保证正弦函数有效取值范围。我们可以通过参数 a 的取值, 来形成不同的心形轮廓, 进而形成动…

android手机解除root,手机显示被root什么意思(手机root怎么解除)

手机root后有什么坏处?如何一键获取手机ROOT权限?在信息时代的大环境下,“黑科技”夺走了大部分的眼球,获取手机root属于所有安卓手机的最大黑科技,也是最基础的搞机技能,本篇就给大家讲解下手机root权限获…

Android11MIUI12,安卓11版MIUI12来了,3款已适配

原标题:安卓11版MIUI12来了,3款已适配现在安卓11系统第二个测试版升级更新都已经推送了,不知道各位有没有升级更新到安卓11系统体验一下新系统。不知道你的手机能不能升级安卓11系统,厂商有没有为你的手机适配安卓11系统&#xff…

html修改details范围,HTML details 标签

HTML 标签标签用于创建一个可展开折叠的元件,用户可以从中检索其他附加的信息。实例使用 元素:Copyright 1999-2011.- by Refsnes Data. All Rights Reserved.All content and graphics on this web site are the property of the company Refsnes Data.…

html中如何设计对话框,用纯css3和html制作泡沫对话框实现代码

现在,泡沫对话框是一种比较流行的趋势,一般都是用html和javascript,和或者图片来实现,今天用纯css3和html来实现一些基本的简单的泡沫对话框html代码如下:复制代码代码如下:The basic bubble variantsThis only needs …

html获取此次点击的id,github项目解析(八)--Activity启动过程中获取组件宽高的三种方式...

转载请标明出处:1片枫叶的专栏上1个github小项目中我们介绍了避免按钮重复点击的小框架,其实现的核心逻辑是重写OnClickListener的onClick方法,添加避免重复点击的逻辑,即为第2次点击与第1次点击的时间间隔添加阙值,若…

minitab怎么算西格玛水平_16:三因子二水平全因子实验设计和MINITAB应用训练

16:思慧慧咨询官网――精益生产、六西格玛黑带、绿带、TRIZ创新发明、实验设计DOE、价值工程、全面设备管理(TPM)培训和项目咨询​www.sihuide.com分享地址:千聊入口1 https://m.qlchat.com/topic/details?topicId20000087131743…

html css position,[CSS]CSS Position 详解

一. CSS position 属性介绍CSS中position属性指定一个元素(静态的,相对的,绝对或固定)的定位方法的类型。有static,relative,absolute和fixed四种取值,默认是static。二. position: staticstatic:没有定位&…

win2008无法用计算机名共享,Windows Server 2008 R2中文件共享

在网上找过很多次相关资料,还是自己整理一下吧。实践了才是自己的,只看永远是别人的。服务器:Server 2008 R2(IP:192.168.1.106);客户端:Server 2008 R2(IP:192.168.1.107)一、 创建用户itjong运…

线性规划图解法求最优解_高中数学:简单的线性规划问题

1. 简单线性规划问题的有关概念先来看一道高考题:某公司招收男职员x名,女职员y名,x和y须满足约束条件,则的最大值是( )A. 80 B. 85 C. 90 D. 95(1)约束条件:变量x、y满足的一组条件,如上面高考题中的二元一…

在桌面关闭计算机关机不了怎么办,为什么我电脑按关机屏幕一直显示正在关机却一直关不了机怎么办...

“开始”-->“运行”-->键入“Regedit”-->“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\control\Shutdown子项,在右边窗口中新建一个"字符串值",命名为"FastReboot",同时将"数值数据"设为0即可。如果还不行再…

spark-sql建表语句限制_SparkSQL

SparkSQL介绍Hive是Shark的前身,Shark是SparkSQL的前身,SparkSQL产生的根本原因是其完全脱离了Hive的限制。SparkSQL支持查询原生的RDD。 RDD是Spark平台的核心概念,是Spark能够高效的处理大数据的各种场景的基础。能够在scala中写SQL语句。支持简单的SQ…

计算机大作业论文意义,大学的大作业是什么?

原标题:大学的大作业是什么?大学里面的大作业一般就是课程设计之类的,一些老师会让学生做些课外实践的作业,作为平时成绩的一部分大作业听起来很高大上,然而好多课程其实只是一篇论文。论文类的就是有点水的了。毕竟学…

arduino智能浇花系统_arduino+水泵+继电器+RFID

arduino继电器电机应用场合:加湿器、自动浇花、智能门锁、报警系统.......总之很多场合都适用。本章就介绍利用RFID卡输入,驱动水泵。/* * ---------------------------------------------------------------------------------------------------------…

7段均衡器最佳调节图_超高级的吉他均衡器 更细腻的控制 你值得拥有

BOSS DD-200吉他均衡器最近 BOSS推出了一款全新的吉他均衡效果器,为了追求更细腻的控制,这一次的更新,EQ200 可以说做出了不少的颠覆性改进。面板上很直观的看到,EQ的推子增加到了10段,外加一个总音量,对于…

京瓷m5021cdn如何设置扫描_京瓷产品让您轻松应对潮湿天气

随着即将到来的四月,中国南方大部分地区也将伴随着雨季的到来。这也意味着很多复印件、打印机将会收到潮湿天气的影响,更容易出现卡纸、图像模糊等一系列问题。而京瓷公司最新推出的“黑金刚”系列增加了特有的感光鼓加热功能,有效减少机器受…