Android异步任务机制之AsycTask
在Android中实现异步任务机制有两种方式,Handler和AsyncTask。 本篇就说说AsyncTask的异步实现。
1、什么时候使用 AsnyncTask
在上一篇文章已经说了,主线程主要负责控制UI页面的显示、更新、交互等。 为了有更好的用户体验,UI线程中的操作要求越短越好。
我们把耗时的操作(例如网络请求、数据库操作、复杂计算)放到单独的子线程中操作,以避免主线程的阻塞。但是在子线程中不能更新UI界面,这时候需要使用handler。
但如果耗时的操作太多,那么我们需要开启太多的子线程,这就会给系统带来巨大的负担,随之也会带来性能方面的问题。在这种情况下我们就可以考虑使用类AsyncTask来异步执行任务,不需要子线程和handler,就可以完成异步操作和刷新UI。
不要随意使用AsyncTask,除非你必须要与UI线程交互.默认情况下使用Thread即可,要注意需要将线程优先级调低.AsyncTask适合处理短时间的操作,长时间的操作,比如下载一个很大的视频,这就需要你使用自己的线程来下载,不管是断点下载还是其它的.
2、AsnyncTask原理
AsyncTask主要有二个部分:一个是与主线程的交互,另一个就是线程的管理调度。虽然可能多个AsyncTask的子类的实例,但是AsyncTask的内部Handler和ThreadPoolExecutor都是进程范围内共享的,其都是static的,也即属于类的,类的属性的作用范围是CLASSPATH,因为一个进程一个VM,所以是AsyncTask控制着进程范围内所有的子类实例。
AsyncTask内部会创建一个进程作用域的线程池来管理要运行的任务,也就就是说当你调用了AsyncTask的execute()方法后,AsyncTask会把任务交给线程池,由线程池来管理创建Thread和运行Therad。
3、AsyncTask介绍
Android的AsyncTask比Handler更轻量级一些(只是代码上轻量一些,而实际上要比handler更耗资源),适用于简单的异步处理。
Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),因为UI的更新只能在主线程中完成,因此异步处理是不可避免的。
AsyncTask:对线程间的通讯做了包装,是后台线程和UI线程可以简易通讯:后台线程执行异步任务,将result告知UI线程。
使用AsyncTask分为两步:
① 继承AsyncTask类实现自己的类
public abstract class AsyncTask<Params, Progress, Result> {
Params: 输入参数,对应excute()方法中传递的参数。如果不需要传递参数,则直接设为void即可。 Progress:后台任务执行的百分比 Result:返回值类型,和doInBackground()方法的返回值类型保持一致。
②复写方法
最少要重写以下这两个方法:
doInBackground(Params…)
在子线程(其他方法都在主线程执行)中执行比较耗时的操作,不能更新UI,可以在该方法中调用publishProgress(Progress…)来更新任务的进度。Progress方法是AsycTask中一个final方法只能调用不能重写。
onPostExecute(Result)
使用在doInBackground 得到的结果处理操作UI, 在主线程执行,任务执行的结果作为此方法的参数返回。
有时根据需求还要实现以下三个方法:onProgressUpdate(Progress…)
可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。
onPreExecute()
这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。
onCancelled()
用户调用取消时,要做的操作
4、AsyncTask示例
按照上面的步骤定义自己的异步类:
public class MyTask extends AsyncTask<String, Integer, String> {
//执行的第一个方法用于在执行后台任务前做一些UI操作
@Override
protected void onPreExecute() {
}
//第二个执行方法,在onPreExecute()后执行,用于后台任务,不可在此方法内修改UI
@Override
protected String doInBackground(String... params) {
//处理耗时操作
return "后台任务执行完毕";
}
/*这个函数在doInBackground调用publishProgress(int i)时触发,虽然调用时只有一个参数
但是这里取到的是一个数组,所以要用progesss[0]来取值
第n个参数就用progress[n]来取值 */
@Override
protected void onProgressUpdate(Integer... progresses) {
//"loading..." + progresses[0] + "%"
super.onProgressUpdate(progress);
}
/*doInBackground返回时触发,换句话说,就是doInBackground执行完后触发
这里的result就是上面doInBackground执行后的返回值,所以这里是"后台任务执行完毕" */
@Override
protected void onPostExecute(String result) {
}
//onCancelled方法用于在取消执行中的任务时更改UI
@Override
protected void onCancelled() {
}
}
在主线程申明该类的对象,调用对象的execute()函数开始执行。
MyTask t= new MyTask();
t.execute();//这里没有参数
5、使用AsyncTask需要注意的地方
AsnycTask内部的Handler需要和主线程交互,所以AsyncTask的实例必须在UI线程中创建
AsyncTaskResult的doInBackground(mParams)方法执行异步任务运行在子线程中,其他方法运行在主线程中,可以操作UI组件。
一个AsyncTask任务只能被执行一次。
运行中可以随时调用AsnycTask对象的cancel(boolean)方法取消任务,如果成功,调用isCancelled()会返回true,并且不会执行 onPostExecute() 方法了,而是执行 onCancelled() 方法。
对于想要立即开始执行的异步任务,要么直接使用Thread,要么单独创建线程池提供给AsyncTask。默认的AsyncTask不一定会立即执行你的任务,除非你提供给他一个单独的线程池。如果不与主线程交互,直接创建一个Thread就可以了。
Android异步任务机制之AsycTask的更多相关文章
- Android异步消息传递机制源码分析
1.Android异步消息传递机制有以下两个方式:(异步消息传递来解决线程通信问题) handler 和 AsyncTask 2.handler官方解释的用途: 1).定时任务:通过handler.p ...
- Android异步消息处理机制(多线程)
当我们需要执行一些耗时操作,比如说发起一条网络请求时,考虑到网速等其他原因,服务器未必会立刻响应我们的请求,如果不将这类操作放在子线程里去执行,就会导致主线程被阻塞住,从而影响用户对软件的正常使用. ...
- 【转载】Android异步消息处理机制详解及源码分析
PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbob ...
- Android异步消息处理机制
安卓子线程无法直接更改UI,所以需要异步消息处理机制来解决 <?xml version="1.0" encoding="utf-8"?><Li ...
- Android 异步消息处理机制解析
Android 中的异步消息处理主要由四个部分组成,Message.Handler.MessageQueue.Looper.下面将会对这四个部分进行一下简要的介绍. 1. Message: Messa ...
- 【转】Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38377229 ,本文出自[张鸿洋的博客] 很多人面试肯定都被问到过,请问Andr ...
- Android 异步消息处理机制 让你在深入了解 Looper、Handler、Message之间的关系
转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/38377229 ,本文出自[张鸿洋的博客] 非常多人面试肯定都被问到过,请问And ...
- Android 异步消息处理机制终结篇 :深入理解 Looper、Handler、Message、MessageQueue四者关系
版权声明:本文出自汪磊的博客,转载请务必注明出处. 一.概述 我们知道更新UI操作我们需要在UI线程中操作,如果在子线程中更新UI会发生异常可能导致崩溃,但是在UI线程中进行耗时操作又会导致ANR,这 ...
- Android异步消息机制
Android中的异步消息机制分为四个部分:Message.Handler.MessageQueue和Looper. 其中,Message是线程之间传递的消息,其what.arg1.arg2字段可以携 ...
随机推荐
- iOS常用设计模式笔记
一.原则 1.单一职责原则 (Single Responsiblity Principle SRP) 2.开闭原则(Open Closed Principle,OCP) 3.里氏替换原则(Liskov ...
- 裁剪Tessdata
一个项目只需要tesseract traineddata 中的数字部分. 实现过程简单说就是解包,去掉多余,再打包.利用了tesseract的dawg2wordlist / wordlist2da ...
- 《zw版·Halcon-delphi系列原创教程》 zw版-Halcon常用函数Top100中文速查手册
<zw版·Halcon-delphi系列原创教程> zw版-Halcon常用函数Top100中文速查手册 Halcon函数库非常庞大,v11版有1900多个算子(函数). 这个Top版,对 ...
- Wireshark工控协议
Wireshark是一个强大开源流量与协议分析工具,除了传统网络协议解码外,还支持众多主流和标准工控协议的分析与解码. 序号 协议类型 源码下载 简介 1 Siemens S7 https://git ...
- Firebug 学习使用教程
Firebug是Firefox下的一个扩展,能够调试所有网站语言,如Html.Css等,但FireBug最吸引人的就是JavaScript调试功能,除此之外,还有对Dom的查看与调试,网站整体分析等其 ...
- [转]SSAS没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG)) (Microsoft Visual Studio)的解决办法
转自:http://www.cnblogs.com/xvqm00/archive/2011/07/15/2107338.html 打开SSAS 数据源视图浏览数据时,提示 没有注册类别 (异常来自 H ...
- HDU 3605:Escape(最大流+状态压缩)
http://acm.hdu.edu.cn/showproblem.php?pid=3605 题意:有n个人要去到m个星球上,这n个人每个人对m个星球有一个选择,即愿不愿意去,"Y" ...
- NTP校时设置
一.Windows Server 2008 – Time Server 前言: 国家时间与频率标准实验室 && NTP服务器 也可以忽略1~6 直接跳7 如果已改过机码请使用 1 ...
- css样式基础三
css的定位: 其中css中被分为块级元素与行内元素.如块级元素div.hx标签.p元素.行内元素span和strong W3school给出的一切皆为框的定义. 而且可以使用display属性,强行 ...
- 20160929001 Guid生成
全局唯一标识符(GUID,Globally Unique Identifier)是一种由算法生成的二进制长度为128位的数字标识符. using System; namespace GUID测试 ...