android消息机制之二--Handler
来源:互联网 发布:素材下载站源码 编辑:程序博客网 时间:2024/05/18 03:55
Android消息机制之—Handler
1.2 Handler
/frameworks/base/core/java/android/os/Handler.java
Handler扮演者向MQ上添加消息和处理消息的角色,它通知MQ它要执行一个任务(sendMessage),并且loop到自己的时候执行该任务,整个过程是异步的。
*A Handler allows you to send and process {@link Message} and Runnable
* objects associated with a thread's {@link MessageQueue}. Each Handler
* instance is associated with a single thread and that thread's message
* queue. When you create a new Handler, it is bound to the thread
* message queue of the thread that is creating it -- from that point on,
* it will deliver messages and runnables to that message queue and execute
* them as they come out of the message queue.
一个Handler允许发送与一个线程相关的Message和Runnable对象。每个Handler实例,都会和一个线程相连。如果创建一个新的Handler,它就会和线程的消息队列相连。
小结:一个线程可以有多个Handler,但只能有一个Looper。
public Handler(Callbackcallback,boolean async) {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() ||klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) ==0) {
Log.w(TAG,"The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
mLooper = Looper.myLooper();//默认关联当前线程的Looper
//looper不能为空,即默认的构造方法只能在looper线程中使用
if (mLooper ==null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
mQueue = mLooper.mQueue;
//直接把关联looper的MQ作为自己的MQ,因此它的消息将发送到关联//looper的MQ上。
mCallback = callback;
mAsynchronous = async;
}
以上就是讲Handler和Looper线程的绑定和联系,下面讲Handler的消息发送和消息处理。
Handler发送消息:
public final boolean post(Runnable r){
return sendMessageDelayed(getPostMessage(r), 0);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
private static Message getPostMessage(Runnable r, Object token) {
Message m = Message.obtain();
m.obj = token;
m.callback = r;
return m;
}
发送Runnable对象,它的run方法将在handler关联的looper线程中执行。在Handler中封装成Message。
post(Runnable),
postAtTime(Runnable, long),
postDelayed(Runnable, long),
sendEmptyMessage(int),
sendMessage(Message),
sendMessageAtTime(Message, long)
sendMessageDelayed(Message, long)
以上这些方法都是向MQ上发送消息的,字面上可见发送的消息为Runnable对象和Message对象。在源码中我们发现,Runnable对象也被封装为了Message对象。
下面分析一下,SendMessage函数,有利于理解Handler的处理过程:
从基本的sendMessage()开始,发现sendMessage调用了sendMessageDelayed()。
public final boolean sendMessage(Message msg){
return sendMessageDelayed(msg, 0);
}
public final boolean sendEmptyMessage(int what){
return sendEmptyMessageDelayed(what, 0);
}
public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}
发现sendEmptyMessageDelayed()最后也调用了sendMessageDelayed().
public final boolean sendMessageDelayed(Message msg, long delayMillis){
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
sendMessageDelayed()调用了sendMessageAtTime();
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
在sendMessageAtTime中,调用了enqueueMessage();
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this; //message的target指向处理它的handler
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
到这消息添加到了MQ中,并且每个消息的target都指向能够处理该消息的handler。
在loop()方法中的关键代码:
msg.target.dispatchMessage(msg);
正常添加的消息为Message对象,而post发出的message,其callback为Runnable对象。
接下来Handler处理消息:
核心方法dispatchMessage();
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
//如果消息设置了callback则为runnable消息,处理callback。
handleCallback(msg);
} else {
//如果handler本省设置了callback,执行callback
if (mCallback != null) {
// 这种方法允许让activity等来实现Handler.Callback接口,避免了//自己编写handler重写handleMessage方法
if (mCallback.handleMessage(msg)) {
return;
}
}
//没有callback,调用handler的钩子方法handleMessage
handleMessage(msg);
}
}
钩子函数由Handler的子类来实现。
/** * Subclasses must implement this to receive messages. */
public void handleMessage(Message msg) {
}
//处理runnable消息—直接运行run方法。
private static void handleCallback(Message message) {
message.callback.run();
}
对于开发者来说,只要实现handleMessage钩子函数和Runnable对象的run方法外,其他的都是透明的。
Handler的用处:
1. 可以在任意线程中发送消息,这些消息会发送到它关联的MQ上。
2. Handler是在它关联的looper线程中处理消息的。
通过Looper,Handler和Message的方式就解决了在非主线程中更新UI的问题。Android的主线程(UI线程)也是一个looper线程。
- android消息机制之二--Handler
- android消息机制 之Handler
- Android之Handler消息机制
- Android之Handler消息机制
- Android之Handler消息机制
- Android消息机制之Handler
- Android消息机制之Handler
- Android之Handler消息机制
- Android消息传递之Handler消息机制
- Android消息传递之Handler消息机制
- Android消息传递之Handler消息机制
- Android系统Handler消息处理机制(二)
- Android消息机制-Handler(二)
- Android消息机制之Looper和Handler
- Android开发之Handler消息传递机制
- Android之Handler消息机制详解
- Android之handler消息传递机制
- Android中的消息机制之Handler
- 添加 struct 类型支持
- Mybatis分库分表扩展插件
- 怎样快速制作婚礼视频
- 作为一个C++的编码者对于当下技术趋势的看法
- 浅谈json,自己初认识json,写下自己对其概念的理解。
- android消息机制之二--Handler
- zabbix server is not running: the information displayed may not be current
- ListView 中Item TextView 跑马灯遇到的问题
- CSS书写应该注意的情况
- activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建
- Python 基础关键字及符号
- 前端 网页设计之颜色对照表
- 使用SimpleDateFormat格式化日期
- Codeforces 629C Famil Door and Brackets