Android学习笔记之消息机制
Android的消息机制主要是指Handler的运行机制以及Handler所附带的MessageQueue和Looper的工作过程。
1.为什么要使用Handler?
Android规定访问UI只能在主线程中进行,如果在子线程中访问UI,则会抛出异常。同时Android建议不能在主线程中进行耗时的操作,不然会导致程序无法响应即ANR。因此耗时的工作只能交给子线程去做,而子线程却不能直接访问UI,为了解决这个矛盾,Android提供了Handler。Handler的主要作用是将某个任务切换到某个指定的线程中去执行。例如,我们在主线程中创建Handler,在子线程执行完耗时任务后,就可以通过Handler将更新UI的操作切换到主线程中去执行。
2.为什么系统不允许在子线程中访问UI?
因为Android的UI控件不是线程安全的,如果在多线程中并发访问可能会导致UI控件处于不可预期的状态。
3.Handler与MessageQueue,Looper
Android的消息机制主要是指Handler的运行机制,Handler的运行需要消息队列(MessageQueue)和消息循环(Looper)的支撑。
消息队列的内部存储结构并不是真正的队列,而是单链表。消息队列只是一个消息的存储单元,不能处理消息,而Looper就是来处理消息的。Looper会无限循环的去查看是否有消息,如果有,就处理,否则一直等待。
Handler创建时会采用当前线程的Looper来构造消息循环系统,如果当前线程没有Looper,则会报错(有的时候,也可以通过构造函数指定一个Looper)。这个当前线程的Looper是通过ThreadLocal来获取的。ThreadLocal并不是线程,它是线程内部的一个数据存储类,通过它可以在指定线性中存储数据和获取数据。
4.MessageQueue工作原理
MessageQueue主要包含两个操作:插入和读取,分别对应enqueueMessage和next两个方法。enQueueMessage是往消息队列中插入一条消息,而next是从消息队列中取出一条消息并将其从消息队列中删除。前面说过,消息队列的内部实现是iyge单链表,它在插入和删除上比较有优势。
这里注意,next方法是一个无限循环的方法,如果消息队列中没有消息,那么next方法会一直阻塞,当有新消息到来时,它会返回这条消息并将其从单链表中删除。
5.Looper的工作原理
(1)Looper会一直不停的从MessageQueue中查看是否有消息,如果有,则会立刻处理,否则就一直阻塞。
为当前信线程创建Looper的方法如下:
new Thead("Thread1"){ @override
public void run()
{
Looper.prepare();
Handler handler=new Handler();
Looper.loop();
}
}
注意,只有调用了Looper的loop方法后,消息循环系统才真正起作用。
loop方法会调用MessageQueue的next方法来获取消息,当没有消息时,next方法会阻塞,导致loop方法也会阻塞。Looper获得消息后,调用Handler对象的dispatchMessage方法,这个dispatchMessage方法是在创建Handler时所使用的Looper中执行的,这样就就将代码逻辑切换到指定的线程中去了。
loop方法是一个死循环,唯一跳出循环的方式是MessageQueue的next方法返回null。当Looper的quit方法被调用时,它会调用MessageQueue的quit或者quitSafely方法来通知消息队列退出,当消息队列被标记为退出状态时,其next方法就会返回null。
(2)Looper也可以退出,主要的方法是quit和quitSafely。前者会直接退出Looper,而后者只是设定一个标记,然后把消息队列中的已有消息处理完毕后才安全退出。Looper退出以后,Handler就无法再顺利发送消息了,其send方法会返回false。
(3)在子线程中创建Looper后,当所有事情完成以后应该调用quit方法来终止消息循环,否则这个子线程会一直处于等待状态。
6.Handler的工作原理
Handler的主要工作是发送和接收消息。消息的发送通过post的方法和send的方法实现,post的方法最终是通过send的方法实现的。
Handler发送消息仅仅是向消息队列中插入一条消息,然后MessageQueue的next方法将消息给Looper处理,最终Looper将消息交给Handler处理,即Handler的dispatchMessage方法被调用。
public void dispatchMessage(Message msg){
if(msg.callback!=null)
{
handleCallback(msg);
}
else
{
if(mCallback!=null)
{ if(mCallback.handleMessage(msg))
{
return;
}
}
handleMessage(msg);
}
}
这里msg.callback对象其实就是一个Runnable对象,就是Handler的post方法所传递的Runnable参数。
mCallback对应的类实现的是Callback接口。当我们不想派生Handler的子类并重写其handleMessage方法时,可以通过Callback来实现。
Android学习笔记之消息机制的更多相关文章
- Android学习笔记(广播机制)
1.Android的广播机制介绍 收听收音机也是一种广播,在收音机中有很多个广播电台,每个广播电台播放的内容都不相同.接受广播时广播(发送方)并不在意我们(接收方)接收到广播时如何处理.好比我们收听交 ...
- android学习笔记21——消息提示Toast
消息提示可细分为两种:大量消息提示——当程序有大量图片.信息需要展示时,采用对话框消息提示: 小量消息提示——当程序只有少量信息需要呈现给用户时,采用轻量级的对话框——Toast; Toast ==& ...
- 【转】 Pro Android学习笔记(八八):了解Handler(2):什么是Handler
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 之前我们有一篇很好的博文<Andro ...
- 【转】Pro Android学习笔记(二):开发环境:基础概念、连接真实设备、生命周期
在Android学习笔记(二):安装环境中已经有相应的内容.看看何为新.这是在source网站上的Android架构图,和标准图没有区别,只是这张图颜色好看多了,录之.本笔记主要讲述Android开发 ...
- Android消息传递之Handler消息机制
前言: 无论是现在所做的项目还是以前的项目中,都会遇见线程之间通信.组件之间通信,目前统一采用EventBus来做处理,在总结学习EventBus之前,觉得还是需要学习总结一下最初的实现方式,也算是不 ...
- Android学习笔记之JSON数据解析
转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...
- 【转】Pro Android学习笔记(九八):BroadcastReceiver(2):接收器触发通知
文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.sina.com.cn/flowingflying或作者@恺风Wei-傻瓜与非傻瓜 广播接 ...
- 【转】 Pro Android学习笔记(六九):HTTP服务(3):HTTP POST MultiPart
目录(?)[-] 建立测试环境 开发环境导入第三方JAR HTTP Post Multipart小例子 HTTP POST不仅可以通过键值对传递参数,还可以携带更为复杂的参数,例如文件.HTTP Po ...
- 【转】 Pro Android学习笔记(六七):HTTP服务(1):HTTP GET
目录(?)[-] HTTP GET小例子 简单小例子 出现异常NetworkOnMainThreadException 通过StrictMode进行处理 URL带键值对 Andriod应用可利用ser ...
随机推荐
- iOS开发】canOpenURLl 和修改http请求
控制台输出 如图是在我启动一个 Xcode + iOS 的 App 之后,控制台的输出. 这在 Xcode 时,是不会有的情况,原因是[为了强制增强数据访问安全, iOS9 默认会把所有从NSURLC ...
- MySQL安装,启动
一.安装.配置环境变量 http://www.cnblogs.com/mr-wid/archive/2013/05/09/3068229.html 配置环境变量:把你的安装目录复制下,例如:G:\Do ...
- NTDLL未文档化函数RtlGetNtVersionNumbers获取操作系统版本
作为新手,对获取操作系统版本号好奇过,因为曾经假象过一个场景:自己的程序在windows xp环境下编译,在windows 2003, windows 7,windows 8是否需要提权或者兼容处理, ...
- REST有状态与无状态的理解
1. 什么是REST? REST(REpresentation State Transfer)表述性状态传递,是一种软件架构风格,是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可 ...
- javascript:void(0)
这是不是一个设计缺陷呢 void(0)这种用法巧妙利用void关键字的特性返回undefined(且没有副作用).因为不是关键字,比如直接使用undefined,内容可能被改写. 再来看为啥使用0,而 ...
- AndroidLinker与SO加壳技术之上篇
1. 前言 Android 系统安全愈发重要,像传统pc安全的可执行文件加固一样,应用加固是Android系统安全中非常重要的一环.目前Android 应用加固可以分为dex加固和Native加固,N ...
- Powerdesigner 设置唯一约束
- [10]APUE:信号
[a] 常用信号 SIGABRT 调用 abort 函数时产生此信号,进程异常终止 SIGALRM 调用 alarm 或 setitimer 函数超时之后产生 SIGCHLD 子进程终止或 stop ...
- C#之不借助第三变量交换两变量值
源码: 1 2 3 4 5 int n1=10, n2=20; n1 = n1 - n2; // -10 n2 = n1 + n2; // 10 n1 = n2 - n1 ...
- Oracle 11g 导库导不出空表问题
Oracle11g 会遇到这样的问题,用exp整库导出的时候,会遇到这样的问题,库里的空表没办法导出 select * from all_all_tables aa where aa.owner='U ...