Google参考了Windows的消息处理机制,在Android系统中实现了一套类似的消息处理机制。学习Android的消息处理机制,有几个概念(类)必须了解:
1. Message
消息,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。
2. Message Queue
消息队列,用来存放通过Handler发布的消息,按照先进先出执行。
3. Handler
Handler是Message的主要处理者,负责将Message添加到消息队列以及对消息队列中的Message进行处理。
4. Looper
循环器,扮演Message Queue和Handler之间桥梁的角色,循环取出Message Queue里面的Message,并交付给相应的Handler进行处理。
图1 类关联关系图
运行机理:
每个线程都可以并仅可以拥有一个Looper实例,消息队列MessageQueue在Looper的构造函数中被创建并且作为成员变量被保存,也就是说MessageQueue相对于线程也是唯一的。Android应用在启动的时候会默认会为主线程创建一个Looper实例,并借助相关的Handler和Looper里面的MessageQueue完成对Activities、Services、Broadcase Receivers等的管理。而在子线程中,Looper需要通过显式调用Looper. Prepare()方法进行创建。Prepare方法通过ThreadLocal来保证Looper在线程内的唯一性,如果Looper在线程内已经被创建并且尝试再度创建"Only one Looper may be created per thread"异常将被抛出。
Handler在创建的时候可以指定Looper,这样通过Handler的sendMessage()方法发送出去的消息就会添加到指定Looper里面的MessageQueue里面去。在不指定Looper的情况下,Handler绑定的是创建它的线程的Looper。如果这个线程的Looper不存在,程序将抛出"Can't create handler inside thread that has not called Looper.prepare()"。
整个消息处理的大概流程是:1. 包装Message对象(指定Handler、回调函数和携带数据等);2. 通过Handler的sendMessage()等类似方法将Message发送出去;3. 在Handler的处理方法里面将Message添加到Handler绑定的Looper的MessageQueue;4. Looper的loop()方法通过循环不断从MessageQueue里面提取Message进行处理,并移除处理完毕的Message;5. 通过调用Message绑定的Handler对象的dispatchMessage()方法完成对消息的处理。
在dispatchMessage()方法里,如何处理Message则由用户指定,三个判断,优先级从高到低:1. Message里面的Callback,一个实现了Runnable接口的对象,其中run函数做处理工作;2. Handler里面mCallback指向的一个实现了Callback接口的对象,由其handleMessage进行处理;3. 处理消息Handler对象对应的类继承并实现了其中handleMessage函数,通过这个实现的handleMessage函数处理消息。
示例代码:
public class MainThread extends Activity {
private static final String TAG = "MainThread";
private Handler mMainHandler, mChildHandler;
private TextView mInfoTextView;
private Button mMsgButton;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mInfoTextView = (TextView) findViewById(R.id.info);
mMsgButton = (Button) findViewById(R.id.msg);
/**
* 没有指定Looper,Handler将绑定创建它的线程的Looper,这里mMainHandler将绑定主线程的Looper
*
* 在主线程中不用显式调用Looper.prepare()创建Looper
*
*/
mMainHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// 接收子线程的消息
Log.i(TAG, "接收到从子线程发送过来的消息 - " + (String) msg.obj);
mInfoTextView.setText((String) msg.obj);
}
};
// 创建并启动子线程
new ChildThread().start();
mMsgButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mChildHandler != null) {
// 构建消息对象
Message childMsg = mChildHandler.obtainMessage();
childMsg.obj = "我是主线程'"
+ mMainHandler.getLooper().getThread().getName()
+ "'";
// 发送消息给子线程
mChildHandler.sendMessage(childMsg);
Log.i(TAG, "发送给子线程的消息 - " + (String) childMsg.obj);
}
}
});
}
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "Stop looping the child thread's message queue");
// 关闭子线程的循环器
mChildHandler.getLooper().quit();
}
class ChildThread extends Thread {
private static final String CHILD_TAG = "ChildThread";
public void run() {
this.setName("ChildThread");
/**
* 初始化消息队列,如果在子线程里创建Handler没有执行Looper.prepare()将报如下错误
*
* Can't create handler inside thread that has not called
* Looper.prepare()
*/
Looper.prepare();
mChildHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
Log.i(CHILD_TAG, "接收到从主线程发送过来的消息 - " + (String) msg.obj);
try {
// 在子线程中可以做一些耗时的工作
sleep(100);
// 构建消息对象
Message toMain = mMainHandler.obtainMessage();
toMain.obj = "我是子线程'"
+ this.getLooper().getThread().getName() + "'";
// 发送消息给主线程
mMainHandler.sendMessage(toMain);
Log.i(CHILD_TAG, "发送给总线程的消息 - " + (String) toMain.obj);
} catch (InterruptedException e) {
Log.e(TAG, e.getMessage());
}
}
};
// 启动子线程消息循环队列,开始处理消息
Looper.loop();
}
}
}
参考资料:
http://www.oschina.net/code/explore/android-2.2-froyo/android/os/Looper.java
http://www.oschina.net/code/explore/android-2.2-froyo/android/os/Handler.java
http://www.oschina.net/code/explore/android-2.2-froyo/android/os/Message.java
http://www.oschina.net/code/explore/android-2.2-froyo/android/os/MessageQueue.java
- 大小: 3.2 KB
分享到:
相关推荐
【Android 开发】: Android 消息处理机制之 Handler 与 Message http://blog.csdn.net/ahuier/article/details/17012005
【Android 开发】: Android 消息处理机制之 Handler 中 sendMessage() 源代码剖析 http://blog.csdn.net/ahuier/article/details/17013647
### Android的消息处理机制详解 #### 一、Android消息处理机制概览 在Android开发中,消息处理机制是非常重要的一个组成部分,它确保了应用程序能够在不同线程之间有效地传递数据和指令,尤其是在更新用户界面(UI)...
Android的消息处理机制是其异步编程的核心组成部分,主要用于在主线程和子线程之间安全地传递数据和执行任务。在Android系统中,由于UI线程是单线程模型,所有的界面更新操作必须在主线程中执行,因此,当需要在子...
在Android系统中,消息处理机制是应用程序中线程间通信的一种关键方式,它涉及到Handler、Message和Looper等组件。本文将深入探讨Message类,特别是它的`obtain()`方法,以及如何在实际应用中使用Message来实现高效...
### Android的消息处理机制详解 #### 一、引言 Android应用程序是通过消息驱动的,它借鉴了Windows的消息处理机制,并在此基础上实现了一套适合移动设备的处理机制。本篇文章将详细探讨Android的消息处理机制,...
Android事件处理机制
在Android系统中,消息处理机制是至关重要的,它允许开发者在不同的线程间进行通信,尤其是主线程(UI线程)与其他工作线程之间。这一机制主要涉及到两个关键组件:`Looper`和`Handler`。下面我们将深入探讨这两个...
【Android消息处理机制详解】 Android应用的运行基于消息驱动模型,这一模型的核心在于Looper、Handler和MessageQueue的协同工作。下面我们将深入理解这三个组件的作用及其交互。 1. **Message(消息)**: - ...
Android应用程序消息处理机制(Looper、Handler)分析
Android消息机制是指Android系统中的线程间通信机制,该机制负责处理事件的...Android通过这些组件的组合,实现了异步消息处理机制,从而使得在进行耗时操作时,UI线程不会被阻塞,确保了应用界面的流畅性和响应性。
那么在Android系统中,消息处理机制是怎么实现的呢?在程序开发时,我们经常会使用Handler处理Message(消息)。所以可以知道Handler是个消息处理者,Message是消息主体。除此之外还有消息队列和消息轮询两个角色。...
在Android系统中,消息传送机制是应用程序中进行异步处理和协调组件间通信的重要手段。这一机制主要涉及到了Handler、Looper和Message三个核心组件。在观看魔乐科技的视频后,可能对某些细节存在疑问,这里我们将...
消息处理详解.zip”提供了一套深入理解Android消息处理机制的源代码示例,适合开发者参考和学习。以下是关于Android消息处理的一些关键知识点: 1. **Handler(处理器)**:Handler是Android中处理消息的核心组件,...
在Android系统中,Handler、Message和Looper构成了一个关键的异步通信机制,即Handler消息处理机制。这个机制允许Android应用程序在不同的线程间传递消息,处理UI更新等操作,是多线程编程中的重要组成部分。下面...
Android消息机制是Android系统中处理线程间通信和异步任务的核心组件,它允许应用程序在不同的线程之间安全地交换数据和执行操作。深入理解这一机制对于开发高效、响应迅速的Android应用至关重要。 首先,我们要...