转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7520700.html

一:基础概念

UI线程:当Android程序第一次启动时,Android会同时启动一条主线程(Main Thread),主线程主要负责处理与UI相关的事件,如用户的按键事件、屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。主线程通常又被称为UI线程,Android只允许UI线程修改Activity里的UI组件。

子线程:在程序的activity中创建、启动的线程为子线程,子线程中不能操作UI组件。

后台任务:后台任务一般用子线程来完成,通常用于执行一些耗时任务如:复杂计算、下载文件等。因为这些操作是与UI线程同时运作的,所以又称为异步操作。

二:异步方式之——消息传递机制

我们知道,只有UI线程才能修改、操作界面组件,那么其他子线程中的信息如何反映到UI中呢?那就需要子线程把信息汇总到UI线程,由UI线程显示到组件上。

这个过程,就是消息传递机制。

1)消息传递机制原理图

2)消息传递机制解释

首先,UI线程中维护一个消息队列MessageQueue、一个循环者Looper、一个处理者Handler:消息队列负责接受、存储其他子线程发送过来的消息,等待UI线程处理;循环者不停地轮询消息队列,每次都提取队首一个消息;处理者负责处理Looper提取出来的消息,并负责把结果在UI进行呈现。其中,MessageQueue和Looper随着UI线程启动而自动创建并运行,Handler则需要手动定义

其次,在UI线程中创建并启动子线程,子线程中通过同一个handler(通常这个handler为acticity代码中的全局变量,因此子线程中可见)来发送消息,从而把消息发送到了当前UI线程的handler对应的消息队列中。

3)实现步骤

根据消息传递机制的原理,我们只需针对实现各个环节需要的东西即可。

首先:定义、创建Handler,重写其中的handlerMessage方法,处理消息

private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
//根据消息内容,作处理
}
}
};

然后:定义子线程,在其中定义发送消息语句

 Runnable runnable = new Runnable() {
@Override
public void run() {
Message message = new Message();
message.what = 消息标签;
mHandler.sendMessage(message); //handler是UI线程中的handler
}
};

最后:根据条件,创建子线程实例并启动

mThread = new Thread(runnable);
mThread.start();

4)应用场景

Handler机制适合多个子线程存在的情况,这样可以把多个子线程发送过来的信息在UI线程中统一处理、绘制呈现。

【附:如果需要在子线程中使用handler和looper,则需要获取到UI线程中的handler、looper对象。具体方法见:http://blog.csdn.net/logicteamleader/article/details/46591499

三:单个异步任务——AsyncTask

消息传递机制看起来比较复杂,涉及到了消息队列的应用,这几乎是大型Web应用的架构层面才会用到的模式了。

如果只是单个的异步任务,用消息传递机制就有些过于麻烦了,为此,Android为我们提供了一个辅助类——AsyncTask。

AsyncTask类,可以理解为异步任务执行者;这个类的设计目的很明确,就是为了“执行一个较为耗时的异步任务(最多几秒钟),然后更新界面”。

1:使用AsyncTask

1)继承AsyncTask,定义子类,重写其中的几个方法:

AsyncTask需要重写5个方法,分别是:

1、onPreExecute方法:准备运行,该回调函数在任务被执行之后立即由UI线程调用,一般可以显示进度条。

2、doInBackground(Params ...)方法:正在后台运行,通常在这里执行耗时的后台计算,计算结果返回给函数,这里如果AsyncTask的第三个参数是Void的话不需要返回,这里不能更新UI,但是可以调用publishProgress(Progress ...)方法完成。

3、onProgressUpdate(Progress ...)方法:进度更新,UI线程在publishProgress(Progress ...)方法调用完成后被调用,一般动态显示一个进度。

4、onPostExecute(Result)方法:完成后台任务,会返回,这里可以进行些UI的操作,比如提醒任务执行的结果,以及关闭掉进度条对话框等。

5、onCancelled方法:取消任务,在调用AsyncTask的cancel()方法的时候调用。

class ViewContentTask extends AsyncTask<Void, Integer, Boolean> {//三个范型分别对应下面doInBackground、onProgressUpdate、onPostExecute三个方法的参数类型
@Override
protected Boolean doInBackground(Void... voids) {
return null;
} @Override
protected void onProgressUpdate(Integer... values) {
} @Override
protected void onPostExecute(Boolean b) {
//操作UI组件
} @Override
protected void onPreExecute() {
} @Override
protected void onCancelled() {
}
}

2)创建异步任务实例,启动异步任务

ViewContentTask  task = new ViewContentTask();
task.execute();

2:AsyncTask工作原理

当一个异步任务被执行时,要经历四步: 
    onPreExecute(),在UI线程中执行,它会在异步任务开始前执行,一般用来设置任务参数; 
    doInBackground, 最重要的方法,在子线程中执行(事实上,只有它在子线程中执行,其他方法都在UI线程中执行)。当onPreExecute结束后,本方法立刻执行,它用   来进行后台的耗时计算,异步任务的参数会被传给它,执行完成的结果会被送给第四步;执行途中,它还可以调用publishProgress 方法来通知UI线程当前执行的进度; 
    onProgressUpdate, 当publishProgress 被调用后,它在UI线程中执行,刷新任务进度,一般用来刷新进度条等UI部件; 
    onPostExecute, 当后台的异步任务完成后,它会在UI线程中被调用,并获取异步任务执行完成的结果。

Android学习笔记十:异步处理的更多相关文章

  1. android学习笔记十——TabHost

    TabHost——标签页 ==> TabHost,可以在窗口放置多个标签页,每个标签页相当于获得了一个与外部容器相同大小的组件摆放区域. 通过此种方式可以实现在一个容器放置更多组件(EG:通话记 ...

  2. 【转】Pro Android学习笔记(三十):Menu(1):了解Menu

    目录(?)[-] 创建Menu MenuItem的属性itemId MenuItem的属性groupId MenuItem的属性orderId MenuItem的属性可选属性 Menu触发 onOpt ...

  3. 【转】 Pro Android学习笔记(二十):用户界面和控制(8):GridView和Spinner

    目录(?)[-] GridView Spinner GridView GridView是网格状布局,如图所示.在了解ListView后,很容易了解GridView.下面是例子的XML文件. <? ...

  4. 【转】 Pro Android学习笔记(十九):用户界面和控制(7):ListView

    目录(?)[-] 点击List的item触发 添加其他控件以及获取item数据 ListView控件以垂直布局方式显示子view.系统的android.app.ListActivity已经实现了一个只 ...

  5. 【转】 Pro Android学习笔记(七十):HTTP服务(4):SOAP/JSON/XML、异常

    目录(?)[-] SOAP JSON和XMLPullParser Exception处理 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog. ...

  6. 【转】 Pro Android学习笔记(四十):Fragment(5):适应不同屏幕或排版

    目录(?)[-] 设置横排和竖排的不同排版风格 改写代码 对于fragment,经常涉及不同屏幕尺寸和不同的排版风格.我们在基础小例子上做一下改动,在横排的时候,仍是现实左右两个fragment,在竖 ...

  7. 【转】Pro Android学习笔记(十四):用户界面和控制(2):Text类控制

    目录(?)[-] TextView 例子1在XML中设置autoLink属性 例子2在代码中设置autoLink属性 EditText AutoCompleteTextView MultiAutoCo ...

  8. 【转】Pro Android学习笔记(十二):了解Intent(下)

    解析Intent,寻找匹配Activity 如果给出component名字(包名.类名)是explicit intent,否则是implicit intent.对于explicit intent,关键 ...

  9. 【转】Pro Android学习笔记(十):了解Intent(上)

    目录(?)[-] Intent基本含义 系统的Intent Android引入了Intent的概念来唤起components,component包括:1.Activity(UI元件) 2.Servic ...

随机推荐

  1. linux syslog详解 转

    分三部分 一.syslog协议介绍 二.syslog函数 三.linux syslog配置   一.syslog协议介绍 1.介绍 在Unix类操作系统上,syslog广泛应用于系统日志.syslog ...

  2. linux的systemctl 命令用法 转

    目录 预热 管理单个 unit 查看系统上的 unit 管理不同的操作环境(target unit) 检查 unit 之间的依赖性 相关的目录和文件 systemctl daemon-reload 子 ...

  3. spring boot对输入的字符串进行html转码

    可以使用HtmlUtils这个类进行操作.具体的可以参考API,或者点出来看.

  4. 获取AppStore上架后的应用版本号

    应用通过审核以后,由开发者设置应用上架,但何时能在appstore搜索到该应用,这个时间不等,有时候15分钟左右有时候2个多小时,以前就是隔一段时间打开网页然后刷新一下,或者搜索一下,查看版本号,操作 ...

  5. Android之Activity与fragment完整生命周期图

    转自:https://github.com/xxv/android-lifecycle

  6. 用layer-list实现弧形进度条

    本文转载自:http://www.linuxidc.com/Linux/2013-04/82743.htm 之前我有写过如何用style或者是layer-list实现自定义的横向进度条(http:// ...

  7. 本地git库gitlab库链接服务器库 idea git 配置 gitlab 配置 git生成ssh公钥

    下载git  https://git-scm.com/ 安装以后会右键菜单出现Git Base Here 点击Git Base Here   输入 cd ~ 进入你的用户根目录 创建文件夹 mkdir ...

  8. 28个HTML5特征、窍门和技术

    原文地址:  http://www.zhangxinxu.com/wordpress/2010/08/%E7%BF%BB%E8%AF%91-%E4%BD%A0%E5%BF%85%E9%A1%BB%E7 ...

  9. OpenCV教程(46) 快速特征检测

        在计算harris特征角时候,我们要在两个方向计算梯度,计算代价有点大.在paper The article by E. Rosten and T. Drummond, Machine lea ...

  10. 细说Request与Request.Params

    在ASP.NET编程中,有三个比较常见的来自于客户端的数据来源:QueryString, Form, Cookie .我们可以在HttpRequest中访问这三大对象,比如,可以从QueryStrin ...