Handler消息传递机制

简介: 在安卓中,出于性能优化的考虑,UI线程操作并不安全,于是Android制定了一个规则:只允许UI线程修改Activity里的组件。但是这条规则又导致了另外一个问题,因为在Android平台上只允许UI线程修改Activity里的UI组件,导致新启动的线程无法动态改变界面组件的属性值。

在安卓中,出于性能优化的考虑,UI线程操作并不安全,于是Android制定了一个规则:只允许UI线程修改Activity里的组件。但是这条规则又导致了另外一个问题,因为在Android平台上只允许UI线程修改Activity里的UI组件,导致新启动的线程无法动态改变界面组件的属性值。但这并不满足开发者的需求,特别是游戏开发者,因为需要让新启动的线程周期性地改变界面组件的属性值,因此就需要Handler的消息传递机制来实现了。

而说到Handler,不得不提的还有与Handler一起工作的组件,Looper和MessageQueue。

每个线程中只能有一个Looper类,它有一个loop方法负责读取MessageQueue中的消息,读到信息之后就把发送该消息的Handler进行处理。而MessageQueue,也就是消息队列,它是采用先进先出的方式来管理Message,根据Looper构造器的源代码就可以看到在创建Looper对象时就在它的构造器中创建了MessageQueue对象,源代码如下:

private Looper () {

      mQueue = new messageQueue();

mRun = true;

mThread = Thread.currentThread();

}

在我们的主线程中,系统初始化了一个Looper现象,程序可以直接创建Handler并通过它发送、处理消息。

通过对Looper的理解,我们也就知道Handler类的作用,也就是在新启动的线程中发送消息和在主线程里面获取、处理消息。可是什么时候该去主线程获取并处理消息呢?这个时候很显然,只能依赖于回调的方式。也就是说,我们只需要重写Handler类中处理消息的方法,当新启动的线程发送消息时,消息会发送与之关联的消息队列中,然后Handler就会不断地从消息队列中获取并处理消息。如下面的代码所示:我们新建了一个Handler的对象,通过dispatchMessage()方法获得消息队列中的message,根据不同的message对界面进行处理:

private Handler mHandler = new Handler() {
    public void dispatchMessage(Message msg) {
        switch (msg.what) {
            case WHAT_REFRESH_SUCCEED:
                setHomeViewData(); // 设置首页中的数据
                mLoadingView.dismiss(); // 关闭加载框
                break;
------------------略------------------------------------------
            default:
        }
    }
};
如上面的代码所示,如果从消息队列获得的消息为WHAT_REFRESH_SUCCEED,那么我们就执行下面一系列的方法,这些方法就不多说了,总是就是和界面UI布局相关的。而在代码的其他一些地方我们可以通过Handler的一些方法发送消息。

Handler类中有下面几种方法用于发送、处理消息:

(1)void handlerMessage(Message msg):这是处理消息的方法,通常用于被重写。

(2)final boolean hasMessage(int What):这个方法是用于检查消息队列中是否包含what属性为指定值的消息。

(3)final boolean hasMessage(int what, Object object):这个方法是用于检查消息队列中是否包含what属性为指定值并且object属性为指定对象的消息。

(4)Message obtainMessage():这个方法是用于获取消息。

(5)sendEmptyMessage(int what):发送空消息,实际上上面就有用到,这个what就是我们的WHAT_REFRESH_SUCCEED。

(6)final boolean sendEmptyMessageDelayed(int what, long delayMillis):这个方法就是指定多少毫秒后发送空消息

(7)final boolean sendMessage(Message msg):立即发送消息

(8)final boolean sendMessageDelayed(int what, long delayMillis):这个方法就是指定多少毫秒后发送消息

在上面的方法中,我们发现(5)和(7)很相似,那么他们有什么区别呢?经过查询资料,我才知道,sendMessage中就是构建了一个Message,然后把这个Message的what设置成sendEmptyMessage方法中的What参数即可。

也就是说当我们使用sendMessage()方法时,我们新建一个Message对象,然后再调用这个对象,类似于下面代码所示:

Message msgObj = mHandler.obtainMessage(WHAT_REFRESH_SUCCEED, model);
mHandler.sendMessage(msgObj);
而我们调用sendEmptyMessage()时,只要直接在里面传一个WHAT_REFRESH_SUCCEED即可,这些都是要根据不同的情况而定,当然在Handler里面的处理也会有一些差别。这就是我近期对Handler的一些学习理解和应用,有错误的地方欢迎指正。

目录
相关文章
|
消息中间件 安全 Android开发
Handler消息传递机制浅析
本节给大家讲解的是Activity中UI组件中的信息传递Handler,相信很多朋友都知道,Android为了线程安全,并不允许我们在UI线程外操作UI;很多时候我们做界面刷新都需要通过Handler来通知UI组件更新!除了用Handler完成界面更新外,还可以使用runOnUiThread()来更新,甚至更高级的事务总线,当然,这里我们只讲解Handler,什么是Handler,执行流程,相关方法,子线程与主线程中中使用Handler的区别等!
80 0
|
缓存 移动开发 网络协议
第 8 章 Netty 编解码器和 Handler 调用机制
第 8 章 Netty 编解码器和 Handler 调用机制
137 0
|
存储 缓存 前端开发
Netty4 事件处理传播机制
Netty4 事件处理传播机制
Netty4 事件处理传播机制
|
Java Android开发
Binder机制中的收发消息及线程池
在阅读《深入理解android内核设计思想》的有关Binder章节的时候,发现书中有部分问题没有很清晰的描述清楚,所以这篇文章主要是针对收发消息的过程和线程池这两个知识点详细展开一下。注意本篇文章并不是介绍Binder机制,而是针对它的两个小细节深入探讨一下,所以建议大家先详细的阅读《深入理解android内核设计思想》中有关Binder章节后对照阅读本篇文章。
311 0
|
消息中间件 存储 缓存
深入理解 Handler 消息机制
深入理解 Handler 消息机制
|
消息中间件 Java Linux
【Android 异步操作】Handler 机制 ( MessageQueue 消息队列的阻塞机制 | Java 层机制 | native 层阻塞机制 | native 层解除阻塞机制 )(一)
【Android 异步操作】Handler 机制 ( MessageQueue 消息队列的阻塞机制 | Java 层机制 | native 层阻塞机制 | native 层解除阻塞机制 )(一)
506 0
|
消息中间件 Java Android开发
【Android 异步操作】Handler 机制 ( MessageQueue 消息队列的阻塞机制 | Java 层机制 | native 层阻塞机制 | native 层解除阻塞机制 )(二)
【Android 异步操作】Handler 机制 ( MessageQueue 消息队列的阻塞机制 | Java 层机制 | native 层阻塞机制 | native 层解除阻塞机制 )(二)
219 0
|
消息中间件 Android开发
【Android 异步操作】Handler 机制 ( MessageQueue 空闲任务 IdleHandler 机制 )
【Android 异步操作】Handler 机制 ( MessageQueue 空闲任务 IdleHandler 机制 )
215 0
|
Android开发 消息中间件