299_Handler发送消息
来源:互联网 发布:java poi设置高度 编辑:程序博客网 时间:2024/05/24 04:25
Handler发送消息
阅读郭霖大神博客的读书笔记
博客地址:http://blog.csdn.net/sinyu890807/article/details/9991569
一.发送消息
new Thread(new Runnable() {
@Override
public void run() {
Message message = new Message();
message.arg1 = 1;
Bundle bundle = new Bundle();
bundle.putString("data", "data");
message.setData(bundle);
handler.sendMessage(message);
}
}).start();
二.如何发送,如何接收
先看看sendMessage方法发送消息
除了sendMessageAtFrontOfQueue()方法,其他方法全都会调用sendMessageAtTime()方法
所以看sendMessageAtTime()
public boolean sendMessageAtTime(Message msg, long uptimeMillis)
{
boolean sent = false;
MessageQueue queue = mQueue;
if (queue != null) {
msg.target = this;
sent = queue.enqueueMessage(msg, uptimeMillis);
}
else {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
}
return sent;
}
传入两个参数,一个message就是我们要发的消息,一个time是发送时间
定义一个boolean值sent为false,
定义一个MessageQueue,把成员变量mQueue赋值给他
如果queue不为空,也就是mQueue不为空
msg.target=this;
sent为queue调用enqueueMessage返回值,也是传入msg和time
返回 sent值
MessageQueue就是一个消息队列,将所有收到的消息以队列的形式进行排列,
并提供入队和出队的方法.
这个类是在Looper的构造函数中创建的,
所以一个Looper也就对应了一个MessageQueue.
所以enqueueMessage也就是入队的方法
三.enqueueMessage方法
final boolean enqueueMessage(Message msg, long when) {
if (msg.when != 0) {
throw new AndroidRuntimeException(msg + " This message is already in use.");
}
if (msg.target == null && !mQuitAllowed) {
throw new RuntimeException("Main thread not allowed to quit");
}
synchronized (this) {
if (mQuiting) {
RuntimeException e = new RuntimeException(msg.target + " sending message to a Handler on a dead thread");
Log.w("MessageQueue", e.getMessage(), e);
return false;
} else if (msg.target == null) {
mQuiting = true;
}
msg.when = when;
Message p = mMessages;
if (p == null || when == 0 || when < p.when) {
msg.next = p;
mMessages = msg;
this.notify();
} else {
Message prev = null;
while (p != null && p.when <= when) {
prev = p;
p = p.next;
}
msg.next = prev.next;
prev.next = msg;
this.notify();
}
}
return true;
}
传入msg和when,返回boolean
如果msg的when不为0,报错:这个消息已经在使用了
如果msg的target为空而且mQuitAllowed为false
报错:主线程不允许退出
如果mQuiting为true,报错:往死线程的Handler发送了消息
如果target为空,mQuiting为true
然后就是对消息按照时间来排序
具体的操作方法就根据时间的顺序调用msg.next,从而为每一个消息指定它的下一个消息是什么。
四.出队方法Looper.loop()
public static final void loop() {
Looper me = myLooper();
MessageQueue queue = me.mQueue;
while (true) {
Message msg = queue.next(); // might block
if (msg != null) {
if (msg.target == null) {
return;
}
if (me.mLogging!= null) me.mLogging.println(
">>>>> Dispatching to " + msg.target + " "
+ msg.callback + ": " + msg.what
);
msg.target.dispatchMessage(msg);
if (me.mLogging!= null) me.mLogging.println(
"<<<<< Finished to " + msg.target + " "
+ msg.callback);
msg.recycle();
}
}
}
这里有一个死循环,一直调用queue的next方法
next方法就是如果当前MessageQueue中存在mMessages(即待处理消息),就将这个消息出队,然后让下一条消息成为mMessages,否则就进入一个阻塞状态,一直等到有新的消息入队。
msg.target.dispatchMessage(msg);
每当有一个消息出队,就将它传递到msg.target的dispatchMessage()方法中
五.Handler中dispatchMessage()方法
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
如果mCallback不为空,则调用mCallback的handleMessage()方法,否则直接调用Handler的handleMessage()方法,并将消息对象作为参数传递过去。
六.最标准的异步消息处理线程的写法
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
0 0
- 299_Handler发送消息
- 赵雅智_handler
- 消息发送
- 发送消息
- 发送消息
- XMPP 发送消息,发送图片
- ios发送消息 注册消息
- 010_Handler 翻译学习
- Android开发_Handler
- android耗时任务_handler
- 137_Handler警告解决方法
- 向线程发送消息
- sendmessage 发送消息
- MDI发送消息
- 调用CMD发送消息
- QQ消息发送器
- 发送广播消息zz
- PostMessage发送click消息
- C下常用文件操作指令的整理
- bootstrap tooltip 回车换行
- 298_DecimalFormat数字格式化
- Simple PHP encrypt and decrypt
- tar 解压通过tftp传输的包时出现了 Skipping to next header错误
- 299_Handler发送消息
- leetcode(7) - Reverse Integer
- 你是不是太浮躁了?
- DOM
- Makefile调试1--输出打印信息
- 单片机==lcd_显示字符串(23)
- MySQL中in和=的区别
- MATLAB中零散语法知识总结之rand()、tic toc、图形句柄
- 如何避免野指针