Android消息机制

Handler代表了Android系统中的消息机制,Android系统中所有的事件都是通过Handler进行传递的。

要理解Handler就不得不知道这几个类 Looper、MessageQueue、ThreadLocal、Thread、ActivityThrad、Message

类介绍

MessageQueue

单链数据结构,用来储存管理系统中的消息

Message

重点是Message的when属性,他代表了消息执行的时间,MessageQueue通过判断当前时间是否大于Message的when时间来判断是否将Message发送非Looper执行

我们通过mHandler.sendMessageDelayed(Message , 1000);发送一个Message的时候实际上就设置这个消息的执行时间是当前时间的1000毫秒之后等同于mHandler.sendMessageAtTime(Message, SystemClock.uptimeMillis() + 1000);

ThreadLocal

ThreadLocal解决了多线程程序的并发问题

它为每一个线程提供了一个独立Looper的变量副本,使得每一个不同线程中的Looper相对独立互不影响

Looper

消息轮询器,它是一个死循环

每一个Looper对象都里面包含了一个MessageQueue

可以理解成使用死循环遍历MessageQueue中的Message,把适合的消息拿出来执行

Looper通过ThreadLocal与线程建立联系,在每一个线程中它都是一个单例,所以可以理解Looper是一个线程安全的单例

分析

Looper创建并与Thread关联

在ActivityThread的mian函数中


Android消息机制_第1张图片

首先调用了Looper.prepareMainLooper(); 为主线程关联了一个Looper

然后调用Looper.loop();开始轮询;

刚才说了Looper是一个死循环,为什么会是死循环呢?因为在学Java的时候就知道,当mian函数执行完所有语句的时候就代表了程序结束,所有Looper在这里做死循环程序就不会退出。

我们可以推断如果让Looper退出死循环的话,我们的程序就退出了


Android消息机制_第2张图片

myLooper() 是拿到当前线程对应的Looper单例

sThreadLocal是ThreadLocal的实例通过set方法将Looper与Thread关联,然后在任何地方通过sThreadLocal.get()可以拿到Thread中的Looper实例



Handler的创建


Handler在创建的时候会通过Looper.myLooper();方法拿到Thread中的Looper对象。如果线程中没有Thread对象Handler将会抛出异常


Android消息机制_第3张图片

所以在子线程中使用Handler我们必须自己调用Looper.prepare();为这个子线程绑定Looper。然后调用Looper.loop();开始这个消息轮询器

Handler于Looper的关系


Android消息机制_第4张图片

我们在使用mHandler.sendMessage()发送一个Message的时候,Handler会将Message和Message执行的时机(Message.when)添加到Looper中的MessageQueue中()。这样Looper在轮询的时候就会在合适的时机拿到这个Message并且执行。

Looper在拿到需要执行的Message的时候会调用Handler.dispatchMessage()方法执行Message。通过这个函数我们可以看出如果Message里面绑定了callback他会先直接执行这个callback而不会执行mCallback.handleMessage方法;这个callback实际上就是一个Runnable对象;

如果Handler中设置了mCallback他会拦截Handler的handleMessage方法;这相当于给Handler增加了一个事件拦截的机制。这个mCallback只能在通过Handler的构造函数传入


总结

通过分析Android的消息机制,我们可以知道我们传入Handler中的Message统统被放到了Looper的MessageQueue中。MessageQueue会在何时的时候发送这个Message给Looper,然后Looper将这个Message发送给Handler执行。

你可能感兴趣的:(Android消息机制)