Android 消息机制

前言

Android的消息机制主要是指Handler的运行机制。
Handler运行需要底层的MessageQueue和Looper进行支撑。
MessageQueue是消息队列,但是他的内存存储结构不是真正的队列,而是采用单链表数据结构来存储消息队列,它只是消息的存储单元,不会处理消息
Looper:会以无限循环的形式去查找是否有消息,有消息就处理,否则就一直等待。
Looper中有一个特殊的概念ThreadLocal,他不是线程,是在每个线程存储数据。
Hander创建的时候会采用当前线程的Looper来构造消息系统,获取当前线程的Looper就要通过ThreadLocal。它可以在不同的线程互不干扰的存储和提取数据,可以获取每个线程的Looper。线程是没有Looper的需要使用Handler的时候就创建Looper。在主线程ActivityThread会自动创建Looper如果在子线程就需要我们自己调用Looper.Preare()

一,Android的消息机制概述

  • 为什么无法再子线程访问UI呢
    ViewRootImpl对UI的操作进行了验证,方法为checkThread
void checkThread(){
          if(mThread!=Thread.currentThread()){
                 throw new CalledFromWrongThreadException(....); 
           }
}

Android的UI控件不是线程安全,如果线程并发访问会导致Ui控件不可控

二,Android消息机制分析

  • ThreadLocal的工作原理
    ThreadLocal是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后,只有在指定线程中可以获取到存储数据,对于其他线程则无法获取到。即可以在不同线程中维护一套数据副本且彼此不互相影响。
    从ThreadLocal的set,get方法可以看出,他们所操作的对象都是当前线程的localValues对象的table数组,因此在不同线程访问同一个ThreadLocal的set和get方法,他们对ThreadLocal所做的读写操作仅仅限于各自线程内部。
  • 消息队列(MessageQueue)的工作原理
    MessageQueue内部实现时以单链表的数据结构来维护队列,在插入,删除比较有优势
    MessageQueue主要包含两个操作,插入和读取,读取操作本身带有删除操作。
    插入对应的方法:enqueueMessage
    读取并移除对应的方法:next(是一个无限循环的方法,如果没有消息,则next方法一直会阻塞在这里,有消息就会返回这条消息并且从单链表中移除)
  • Looper工作原理
    Looper在Android中扮演消息循环的角色,不停地查看MessageQueue中是否有新的消息。
    Hander需要Looper,没有Looper的线程就会报错,通过Looper.prepare()方法创建一个Looper,再通过Looper.loop()开启消息循环查询
    Looper提供了quit和quitSafely方法退出looper,quite为直接退出,quitSafetly只是设定一个标记,然后把消息队列中的已有消息处理完才会安全退出。
    Looper中的loop方法是一个死循环,唯一终止的方法就是MessageQueue的next方法返回null 则会停止,当调用的退出方法,则next方法就会返回空,否则loop就会一直无限循环,next方法也会一直阻塞。当有消息产生,loop就会处理这个消息,msg.target.dispatchMessage方法来处理,相当于交给了Handler的dispatchMessage,这个时候就切换到了指定线程了。
    注:主线程ActivityThread系统在自动生成了Looper所以不需要我们手动去调用
  • Handler的工作原理

主要负责发送消息和接收消息
post的方法最后都是调用时send方法
Handler发送一条消息,向消息队列中插入一条消息,MessageQueue就会通过next方法将其交给Looper,Looper在经过处理,结束后通过disPatchMessage交还给Hander处理最后调用handlerMessage方法

  • 主线程的消息队列
    主线程就是ActivityThread,通过Looper.prepareMainLooper()创建主线程的Looper以及MessageQueue通过Looper.loop()来进行消息轮询

ActivityThread用过ApplicationThread和ASM进行进程间通信,AMS以进程通信的方式完成ActivityThread的请求后悔回调ApplicationThread中的Binder方法,然后AppplicationThread会想Hander发送消息,收到消息后会将ApplicationThread的逻辑切换到ActivityThread中去执行,即回到了主线程进行操作。

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