Android——Handler机制

  1. 首先在执行ActivityThread这个UI线程入口类的时候,在其main()方法中会创建Looper和MessageQueue,其中Looper是直接new出来,并被放入到了当前前程的ThreadLocal(实现原理)中。而在new Looper的时候,就会在Looper的构造函数中new 出一个MessageQueue。然后会不断的执行获取消息的方法:Looper.loop();取出一个Message,然后调用msg.target.dispatchMessage()进行消息转发,交给对应的handler进行处理(handleMessage())。其中loop()方法是一个死循环,没有消息时就会阻塞,因此Activity可以在没有任何操作的时候可以不退出。
  2. 在new Handler的时候,就会在其构造方法中获取到Looper和MessageQueue的对象,Handler发送消息,sendMessage的所有重载,实际最终都调用了sendMessageAtTime()方法。然后就会将message放入到消息队列中,在放入消息队列的时候,会根据when(消息时间)对消息队列进行重排序,此时如果有消息要被取出,就会唤醒主线程。enqueueMessage把消息通过重新排序放入消息队列。

Linux的一个进程间通信机制:管道(pipe)。原理:在内存中有一个特殊的文件,这个文件有两个句柄(引用),一个是读取句柄,一个是写入句柄

  • 主线程Looper从消息队列读取消息,当读完所有消息时,进入睡眠,主线程阻塞。子线程往消息队列发送消息,并且往管道文件写数据,主线程即被唤醒,从管道文件读取数据,主线程被唤醒只是为了读取消息,当消息读取完毕,再次睡眠。
  1. 消息队列是依靠单链表进行维护的。因为随时都有消息可能被插入并进行重新排序,因此不能使用Queue或者stack等数据结构,或许优先队列(堆)是一个不错的选择,但是实现较复杂,并且消息应该不会特别多,所以没有使用优先队列。
  2. message对象的target属性,用于记录该消息由哪个Handler创建,在obtain方法中赋值,因此looper在转发消息的时候,可以直接交给对应的handler进行消息的处理。
  3. 为什么要用Handler机制,而不直接采用多线程更新UI,是为了更好的处理并发。
    线程封闭不仅使复杂的并发问题简单化,并且避免了线程死锁,这和swing的原理是差不多的。

你可能感兴趣的:(Android——Handler机制)