Looper与Handler是如何通过Message发生关系的
来源:互联网 发布:淘宝网店图片尺寸 编辑:程序博客网 时间:2024/05/09 10:48
经常看到Android的消息用法大概为:
Looper.prepare()
Looper.myLooper();
xxxHandler = new Handler() {
handleMessage(Message msg){...}
};
Looper.loop();
刚开始搞不清楚状况, 根据名字完全看不出有什么关系的两个类,到底如何进行消息传递呢? 只是知道就这么用就没问题的, 应该不少人跟我一样吧.
如然有兴趣来解刨一下吧.
Looper.prepare(); 里面有一句 sThreadLocal.set(new Looper());
这里就new 了一个Looper了, 然后放到ThreadLocal里面, 这是个线程数据共享的一个类.
private Looper() {
mQueue = new MessageQueue();
mRun = true;
mThread = Thread.currentThread();
}
在这里面就传递了当前的工作线程的信息,并且new了一个message queue,就是消息队列嘛, 用来接收消息的容器.
public static Looper myLooper() {
return sThreadLocal.get();
}
这个函数就返回了上面创建的那个new Looper();
public Handler() {
...
mLooper = Looper.myLooper();
mQueue = mLooper.mQueue;
...
}
在这里就把当前线程的Looper赋给Handler了, 这就发生关系了.
可能有同学还会有疑问, 上面是两个类的不同的语句Looper.myLooper();怎么得到的是同一个呢?
那就分析一下吧;
在Looper类里面有个全局的静态容器
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
再进入ThreadLocal类里面看
public void set(T value) {
Thread currentThread = Thread.currentThread();
Values values = values(currentThread);
if (values == null) {
values = initializeValues(currentThread);
}
values.put(this, value);
}
在这里就把当前的线程的相关信息设进去了.
看看get()函数;
public T get() {
// Optimized for the fast path.
Thread currentThread = Thread.currentThread();
Values values = values(currentThread);
if (values != null) {
Object[] table = values.table;
int index = hash & values.mask;
if (this.reference == table[index]) {
return (T) table[index + 1];
}
} else {
values = initializeValues(currentThread);
}
return (T) values.getAfterMiss(this);
}
再这里就返回了当前线程的相关信息.
因为ThreadLocal是个模板容器, 声明为ThreadLocal<T>
在Looper中声明为ThreadLocal<Looper> , 所以 T == Looper .
简单的翻译一下上面的get()和set()吧;
public void set(Looper value) {
values.put(this, value);
}
public void Looper get() {
return values.get(this);
}
这样就很清晰了, 关系就是这么发生的. 回头梳理一下吧.
Looper.prepare()
Looper.myLooper();
xxxHandler = new Handler(){ handleMessage(Message msg){...} };
Looper.loop();
等价于
Looper.prepare() { sThreadLocal.set(currentThread, new Looper(); }
Looper.myLooper() { sThreadLocal.get(currentThread) }
new Handle(){
...
mLooper = sThreadLocal.get(currentThread);
mQueue = mLooper.mQueue;
...}
关系发生了,这时候就可以通过Message进行通信了, 这就不多说了.
from : http://www.2cto.com/kf/201212/177537.html
- Looper与Handler是如何通过Message发生关系的
- Looper与Handler是如何通过Message发生关系的
- Handler,Looper,Message的理解与困惑
- Handler、Looper、Message与HandlerThread
- Android:Message、Handler、Message Queue与Looper
- Handler,Message,Looper的关系
- Handler、Looper、Message的理解
- Android的Message机制---Handler、Message、Looper
- 通过handler与message
- 消息机制--Message.Handler与Looper(1)
- 消息机制--Message.Handler与Looper(2)
- Handler,MessageQueue,Runnable,Message与Looper
- Handler、Looper与message消息机制
- Android Handler、Message、MessageQueue与Looper介绍
- Android Looper、Handler与Message邂逅
- [推荐]Android消息处理机制(Handler、Looper、MessageQueue与Message) Android是消息驱动的,实现消息驱动有几个要素: 消息的表示:Message 消息
- Message,MessageQueue,Looper,Handler的理解
- 关于android Handler Message Looper的理解
- Android中的Handler, Looper, MessageQueue和Thread
- 如何在CentOS 6 下启动ORACLE 11
- ubuntu github指南
- HDU 1561 树形DP+有依赖的背包
- web客户端存储数据
- Looper与Handler是如何通过Message发生关系的
- 《软件需求规格说明》中的状态和方式——GJB438B学习笔记之十四
- Syslog协议介绍
- 在linux下面比较两个文件及打补丁整理 <diff> - <patch>
- linphone-3.5.0 语音模块编译与移植
- fragment 替换时产生 Recursive entry to executePending 的错误
- listView中的按钮不生效
- SVN服务器搭建和使用(一)
- C语言 文件操作