——————Hnadler实现细节
– 功能
——执行计划任务
——线程间通信
——-确保操作始终在某个特定的线程中执行
– 结论
——1在同一线程可以创建不同的handler
——2handler不能直接创建在没有Looper.prapare这种函数的线程中
——3通过对handler指定Looper才能在不同的线程中运行
——4 一旦message被开始处理,removeMessage是无效的
上面是关于handler的原理,其中我们发现,承担线程通信功能其实是looper,通过不断的从消息队列中取出数据,发送个handler,由handlerMessage()来接受消息
对上面的 测试的代码在下面,可以直接下载,也可以自己写demo进行测试
——源码分析
handler的源码实现
Handler()调用了Handler(Callbackcallback,booleanasync)方法,在这个方法中
上面是部分的源码,内部创建了Looper对象,如果mLooper不存在的情况下,就爆出了异常
来看看Looper.myLooper的实现
调用了线程的get方法
Static final ThreadLocal<Looper> sThreadLocal=new ThreadLocal<Looper>();
是一个线程池。存放了Looper,当我们直接去取,当然如果没有内容,就会出错,这也是子线程调用出错的原因,但是在主线程中调用为什么就不会报错,原因是,下面是ActivityThread的源码,也就是activity启动的类,
public static final void main(String[] args) {
SamplingProfilerIntegration.start();
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
Looper.loop();
if (Process.supportsProcesses()) {
throw new RuntimeException("Main thread loop unexpectedly exited");
}
thread.detach();
String name = (thread.mInitialApplication != null)
? thread.mInitialApplication.getPackageName()
: "<unknown>";
Slog.i(TAG, "Main thread of " + name + " is now exiting");
}
默认就已经开启了Looper循环,那么我们看看 Looper.prepareMainLooper();和Looper.loop()做了什么
下面是最终的调用,向线程中添加个一个loop
在创建的Loop时,干了什么?
创建了一个消息队列,对,就是用来存放sendMessage消息的队列,所以当我们在子线程中创建时,就需要调用Looper.prepare().当然还有Looper.loop(),去看看干了什么
看到这里,仿佛一切都懂了,拿到消息队列,然后通过一个死循环一直重里面去取数据,那么我们回去看看我们重写的sendMessage()的实现
里面使用了延迟发送,最终调用了
先是取出当前的消息队列,别告诉我mQueue在哪实现的,前面说过了,在loop()里面,
继续前进——————–>>>>>>>
先是判断了是否是异步的,queue.enqueneMessage()入队,这里还有注意的的msg.target这个代码,如果当前的里面存放了两个hanler,通过这个target就能知道是发送给哪个handler,这里的this就是当前的handler
那么回到Looper方法里面,我们看看被添加到消息队列里面的消息怎么被拿出来的
看出重点来了吗?? Msg.target.dispatchMessage(msg); 这句解释了我上面说的,发送消息被其他handler接收的担忧,那么也就是说真正的消息对列会通过handler.dispatchMessage()将消息取出,那么看看吧,
看到这 ,懂了,里面调用了handleMessage()方法,这个方法就是我们实现的那个方法,好吧,handler分析完毕
handler总结
Handler实例与消息处理是关联的,发送和接受需要匹配
只能依附在HandlerThread
可以通过设置Looper来选择Looper来选择器依附的线程
所有的操作都是在用一个线程
removeMessage只能移除队列总的Message
下面是自己写的测试demo以及
部分的系统源代码
demo下载