Win32窗口消息机制 x Android消息机制 x 异步执行

时间:2024-01-20 14:38:15

如果你开发过Win32窗口程序,那么当你看到android代码到处都有的mHandler.sendEmptyMessage和

private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_REPORT_PRIMARY_CLIP_CHANGED:
reportPrimaryClipChanged();
}
}
};

不禁叹出,这不就是窗口消息机制吗?只是不关窗口的事了,然后分离出来消息机制。
sendMessage这个函数,我们查看窗口属性,改变窗口属性,通知窗口发生事件一切的一切仿佛都在调用这个函数。
WinProc这个消息处理函数,即使你在android的java代码里换了个名handleMessage,我们就认不出你来了吗?
就连Message也同样是一个整形,同时携带两整形参数(windows窗口消息c代码中可以放指针,android消息java代码另外还有Bundle,

Object引用参数,因为int不可以转换对象引用)

这样就很容易理解了:
在windows中,向一个窗口发送窗口消息,实质就是向创建窗口所在的线程的消息队列发送窗口消息,或阻塞等待处理或不阻塞。
在android中,向一个Handler发送消息,同样是在向这个Handler关联的线程的消息队列发送消息,并且不阻塞不等待处理。
在Win32窗口消息机制,消息在消息循环中分派。
在android中,Looper封装了这个消息循环以及消息队列,并在线程的TLS中存放其引用(指针),对于线程唯一存在。如果在实例

Handler时不指明Looper默认借用当前线程的Looper。Handler关联某一个Looper,一个Looper唯一关联一条线程。向Handler发送消息

就是向Looper的消息队列发送(入队)消息,线程必须执行Looper.loop消息循环,消息才能分派。

要注意就是:
窗口在Windows系统是系统范围的,我们可以利用窗口消息进行进程间通讯。而android的Handler却不是。
窗口在Windows系统在创建它的线程上处理消息,任何线程都可以创建窗口。而android的窗口(视图)只能在主线程创建和访问。
在android的消息机制中,还可以发送一个Runnable到某一线程的消息循环中执行,这点就仿如iOS的GCD中的dispatch_async代码块。

参看源代码:

public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}

Java异步线程执行代码块:

mHandler.post(new Runnable() {
public void run() {
// ....
}
});

OC异步线程执行代码块:

dispatch_async(global_queue, ^{
// ....
});