文档章节

Handler消息机制

troy1991
 troy1991
发布于 2016/02/22 16:39
字数 602
阅读 3
收藏 0

消息机制主要分为4个部分

1 消息本身Message

2 消息队列MessagQuere

3 消息循环Looper

4 消息处理Handler

一个线程想要实现消息循环应该怎么做呢?

简单讲原理是这样的:

1初始化Looper

new一个Looper绑定在该线程上,创建Looper的同时,内部创建了一个MessageQuere。

2 调用Looper

从Looper获取到MessageQuere,建立一个while(true)循环,不断的从队列中获取消息,没有消息则返回,将消息发送出去后,释放消息占用的资源。

具体做法如下:

1调用Looper.prepare();

这句话完成MessageQuere和Lopper的初始化

具体代码如下:

1. public static final void prepare() {  

2.         if (sThreadLocal.get() != null) {  

3.             throw new RuntimeException("Only one Looper may be created per thread");  

4.         }  

5.         sThreadLocal.set(new Looper(true));  

6. }

 

1. private Looper(boolean quitAllowed) {  

2.         mQueue = new MessageQueue(quitAllowed);  

3.         mRun = true;  

4.         mThread = Thread.currentThread();  

5. }  

 

2调用Looper.loop();

具体代码如下

1. public static void loop() {  

2.         final Looper me = myLooper();  

3.         if (me == null) {  

4.             throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");  

5.         }  

6.         final MessageQueue queue = me.mQueue;  

7.   

8.         // Make sure the identity of this thread is that of the local process,  

9.         // and keep track of what that identity token actually is.  

10.         Binder.clearCallingIdentity();  

11.         final long ident = Binder.clearCallingIdentity();  

12.   

13.         for (;;) {  

14.             Message msg = queue.next(); // might block  

15.             if (msg == null) {  

16.                 // No message indicates that the message queue is quitting.  

17.                 return;  

18.             }  

19.   

20.             // This must be in a local variable, in case a UI event sets the logger  

21.             Printer logging = me.mLogging;  

22.             if (logging != null) {  

23.                 logging.println(">>>>> Dispatching to " + msg.target + " " +  

24.                         msg.callback + ": " + msg.what);  

25.             }  

26.   

27.             msg.target.dispatchMessage(msg);  

28.   

29.             if (logging != null) {  

30.                 logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);  

31.             }  

32.   

33.             // Make sure that during the course of dispatching the  

34.             // identity of the thread wasn't corrupted.  

35.             final long newIdent = Binder.clearCallingIdentity();  

36.             if (ident != newIdent) {  

37.                 Log.wtf(TAG, "Thread identity changed from 0x"  

38.                         + Long.toHexString(ident) + " to 0x"  

39.                         + Long.toHexString(newIdent) + " while dispatching to "  

40.                         + msg.target.getClass().getName() + " "  

41.                         + msg.callback + " what=" + msg.what);  

42.             }  

43.   

44.             msg.recycle();  

45.         }  

46. }  

此时这个线程已经有了一个消息队列。

通过上述代码,我们可以了解到一个Looper是如何循环消息的,接下来我就说明如何将一个消息加入到消息循环当中。

是通过Handler将消息推送到消息队列当中。

首先初始化一个Handler,此过程中会拿到该线程上的Quere,

Hander通过sendMessage,最终会调用queue.enqueueMessage(msg, uptimeMillis);

通过while(true)循环,最终会调用到handerMessage中。

到此,整个消息流程完整走完。

 

 


© 著作权归作者所有

troy1991
粉丝 0
博文 4
码字总数 1349
作品 0
私信 提问
Android开发之道(10)Handler本质简析与使用实例

Android 开发之道(10)Handler本质简析与使用实例 作者:柳大·Poechant 邮箱:zhongchao.ustc@gmail.com 博客:blog.csnd.net/poechang 日期:March 19th, 2012 1 Overview 先浅析本质太过...

晨曦之光
2012/04/24
85
0
深入理解Android消息处理系统——Looper、Handler、Thread

熟悉Windows编程的朋友可能知道Windows程序是消息驱动的,并且有全局的消息循环系统。而Android应用程序也是消息驱动的,按道理来说也应该提供消息循环机制。实际上谷歌参考了Windows的消息循...

惊天
2011/07/26
0
0
# Handler在多线程间进行消息通信

Handler在多线程间进行消息通信 主要控件:Handler+Message+MessageQueue+LooperHandler机制及其相关用法: 在andriod世界里handler的作用主要用来处理线程间通信,即我们常说的消息机制,那...

Scus
2017/11/22
0
0
浅析Android中的消息机制

在分析Android消息机制之前,我们先来看一段代码: 这段代码似乎看上去很正常,但是当你运行时就会发现,它会报一个致命性的异常: 到底是怎么回事呢?原因在于,Android系统中的视图组件并不...

hanzhankang
2014/01/25
0
0
Android 一起来看看面试必问的消息机制

前言 谈到 Android 的消息机制,相信大家应该不陌生,在日常开发中不可避免要接触到这方面的内容,而且这也是面试中常被问到的内容,最近本着「Read the Fucking Source Code」的原则,每天花...

developerHaoz
2017/10/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Jenkins系列_插件安装及报错处理

进入Jenkins之后我们可以进行插件的安装,插件管理位于以下模块: 发现上面报了一堆错误,是因为插件的依赖没有安装好,那么这一节,就先把这些错误解决掉吧。解决完成后,也就基本会使用插件...

shzwork
今天
2
0
mysql mysql的所有查询语句和聚合函数(整理一下,忘记了可以随时看看)

查询所有字段 select * from 表名; 查询自定字段 select 字段名 from 表名; 查询指定数据 select * from 表名 where 条件; 带关键字IN的查询 select * from 表名 where 条件 [not] in(元素...

edison_kwok
昨天
9
0
多线程同时加载缓存实现

import com.google.common.cache.Cache;import com.google.common.cache.CacheBuilder;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorServi......

暗中观察
昨天
3
0
利用VisualVM 内存查看

准备工作,建几个测试类。等下就是要查看这几个类里面的属性 package visualvm;public class MultiObject { private String str; private int i; MultiObject(String str...

冷基
昨天
2
0
组装一台工作游戏两用机

一、配置清单如下: 分类 项目 价格(元) 主板 华硕(ASUS)TUF Z370-PLUS GAMING II 电竞特工 Z370二代 支持9代CPU 1049 CPU 英特尔(Intel) i7 8700K 酷睿六核 盒装CPU处理器 2640 风扇 九...

mbzhong
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部