Handler是事件驱动的,它的事件分发和接受有点像生产者消费者的模式,简单来说就是,Handler通过looper将message传递到Messagequeen,然后,looper,又不断的从messagequeen里面获取msg然后传递给handler。那么它的原理是怎么样的呢?我一一从这四个类的源码慢慢详细解答出来。
首先来了解下Message,Message作为一个传输组件,其实里面就是封装Runnable,并且它包含了事件的相关的信息以及这个事件的处理者和发送者Hanlder。
public final boolean postDelayed(Runnable r, longdelayMilli s){在post中,调用函数,就是将Runnable传入
return sendMessageDelayed(getPostMessage(r),delayMillis);
}
private static Message getPostMessage(Runnable r) {
Message m =Message.obtain();将Runnable包装到msg中
m.callback = r;
returnm;
}
msg.target.dispatchMessage(msg); 具体体现在Looper里面的这行代码可以看出来。
其实里面的数据结构有点复杂,具体不表述了,我也看不太明白。
接着来看一下messagequeen,作为一个app,它有一个application,也就是一个进程,而一个进程都有一个默认的messagequeen,这个messagequeen里面就是不断会有looper发送message和取出message交给handler来处理。类似于生产者消费者,message就是产品,messagequeen就是传送,handler就是消费者,looper就是生产者。
至于looper就是一个执行者,他具体是从ThreadLocal里面来,也存在ThreadLocal里面,至于我们常常说的UI线程才能更新ui就是因为我们在初始化一个app的时候,会执行这段代码
public static void main(String[] args) {这是在ActivityThread里面执行的main方法里面关于looper的代码
Looper.prepareMainLooper();
Looper.loop();
}
其实说白了,就是app会有一个默认的messagequeen,它也有一个默认的looper,并且他们都属于UI线程下面,所以它里面传递,消费的message就是要在UI线程里执行的message,所以handler处理必须要在UI线程更新UI。
而在子线程创建handler的时候,looper也会随之创建,而这个looper是通过ThreadLocal的get方法通过当前线程获取的,所以looper从messagequeen里面取出和存入的message是传递给子线程里面的handler的,因为子线程创建的looper只能被子线程访问。