ThreadLocal的工作原理
所操作的对象都是当前线程的localValues对象的table数组,因此在不同线程中访问同一个ThreadLocal的set和get方法,他们所做的读写操作仅限于各自线程的内部,这就是为什么ThreadLocal可以在多个线程中互不干扰的存储和修改数据,理解ThreadLocal的实现方式由于与理解Looper的工作原理
10.2.2 消息队列的工作原理
消息队列在Android中指的是MessageQueue,MessageQueue主要包含两个操作:插入和读取。读取操作本身会伴随着删除操作,插入和读取对应的方法分别是enqueueMessage和next,其中enqueueMessage的作用是往消息队列中插入一条消息,而next的作用是从消息队列中取出一条消息并将它从消息队列中移除,尽管messageQueue叫做消息队列,但是他的内部实现并不是用的队列,而是单链表,单链表在插入和删除上比较有优势。
从enqueueMessage中的实现来看,他的主要操作其实就是单链表的插入操作。
next方法是一个无限循环的方法,如果消息队列没有消息,那么next方法会一直阻塞在这个,那么当新消息到来时,next方法会返回这条消息并将其从单链表中移除
10.2.3 Looper的工作原理
Looper的loop方法的工作过程比较好理解,loop方法是一个死循环,唯一跳出循环的方式是MessageQueue的next方法返回了null。当Looper的quit方法被调用时,Looper会调用MessageQueue的quite或者quitSafeley方法来通知消息队列退出,当消息队列被标记为退出状态时,他的next方法会返回null。也就是说,Looper必须退出,否则Loop方法就会无限循环下去。loop方法会调用MessageQueue的next方法获取新消息,而next是一个阻塞操作,当没有消息时,next方法会一直阻塞在哪里,这也导致loop方法一直阻塞在哪里。如果MessageQueue的next方法返回了新消息,Looper就会处理这条消息:msg.target.dispatchMessage(msg),这里的msg.target是发送这条消息的handler对象。这样handler发送的消息最终又交给了它的dispatchMessage方法来处理了。但是这里不同的是,Handler的dispatchMessage方法是在创建handler时所使用的Looper中执行的。这样就成功的将代码切换到了指定的线程中去了
10.2.4 Handler的工作原理
Handler发送消息的过程仅仅是像消息队列中插入了一条信息,MessageQueue的next方法就会返回这条消息给Looper,Looper收到消息后就开始处理了。最终消息由Looper交由给handler处理,既handler的dispatchMessage方法会被调用,这时候handler就会进入了处理消息的阶段。
handler的处理消息的过程如下:
首先检查message的callback是否为null,不为null就通过handleCallback来处理消息。Message的callback是一个Runnable对象,实际上就是Handler的post方法所传递的Runnable参数。其次检查mCallback是否为null,不为null就调用mCallback的handleMessage方法来处理消息。最后调用handler的handleMessage方法来处理消息。
10.3主线程的消息轮询
android的主线程就是ActivityThread,主线程的入口方法为main,在main方法中系统会通过Looper.preparemainLooper()来创建主线程的Looper以及MessageQueue,并通过Looper.loop()来开启主线程的消息循环。
主线程的消息循环开始了以后,ActivityThread还需要一个handler和消息队列进行交互,这个handler就是ActivityThread.H ,他内部定义了一组消息类型,主要包含了四大组件的启动和停止等过程
ActivityThread通过ApplicationThread和AMS进行进程间通信,AMS以进程间通信的方式完成ActivityThread的请求后会回调ApplicationThread中的Binder方法,然后ApplicationThread会像H发送消息,H收到消息后会将ApplicationThread中的逻辑切换到ActivityThread中去执行,既切换到主线程中去执行,这个过程是主线程的消息循环模型。
网友评论