如果你开发过 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, ^{
- // ....
- });
来源: