Android的消息机制

从开发角度来说,Handler是Android消息机制的上层接口,这使得开发过程中只需要和Handler交互即可。

1.1、Android的消息机制概述

简单来讲,Handler的运行需要底层的MessageQueue和Looper的支撑。MessageQueue是消息队列,它的内部存储了一组消息,以队列的的形式对外提供插入和删除的工作,它的内部是采用单链表的数据结构来存储消息列表。Looper可以理解为消息循环。Looper会以无限循环的形式在MessageQueue中查找是否有新消息,如果有就处理消息,否则一直等待着。Looper中还有一个特殊的概念,那就是ThreadLocal,ThreadLocal并不是线程,它的作用是可以在每个线程中存储数据

Handler创建的时候会采用当前线程的Looper来构造消息循环系统,ThreadLocal可以再不同的线程中互不干扰地存储并提供数据通过ThreadLocal可以轻松的获取每个线程的Looper

注意,线程默认是没有Looper的,如果需要使用Hnadler就必须为线程创建Looper。我们经常提到的主线程也叫UI线程,他就是ActivityThreadActivityThread被创建时就会初始化Looper,这也是主线程中默认可以使用Handler的原因。

Android无法在子线程中更新UI,因为Android的UI控件不是线程安全的。

注意,Looper是运行在创建Handler所在的线程中的,这样一来Handler中的业务逻辑就会被切换到创建Handler所在的线程中去执行了

1.2、Android的消息机制分析

1.2.1、ThreadLocal的工作原理

ThreadLocal是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据。只有在指定的线程中可以获取到数据。

不同的线程创建了不同的Values,Values下有不同的数组table,所以不同的线程存储的数据不同

1.2.2、MessageQueue的工作原理

MessageQueue包含两个操作:插入和读取。读取操作本身伴随着删除操作,插入和读取对应的方法分别是enqueueMessage(插入一条消息到消息队列)和next(取出一条消息并将其从消息队列中移除)。

1.2.3、Looper的工作原理

private Looper(boolean quitAllowed){

          mQueue = newMessageQueue(quitAllowed) ;

          mThread = Thread.currentThread() ;

}

从构造方法可以看出,Looper会创建一个MessageQueue,然后将当前线程对象保存

Handler的工作需要Looper,没有Looper的线程就会报错。创建Looper:

Looper.prepare()即可为当前线程创建一个Looper,接着通过Looper.loop()来开启消息循环

Looper提供了quit(直接退出)和quitSafely(消息队列里的消息执行完毕才退出)来退出一个Looper。

子线程中如手动创建了Looper,所有事情处理完后应该调用quit,否则子线程一直等待状态。

当Looper方法是一个死循环,唯一跳出循环的方式是MessageQueue的next方法反回了nul。当Looper的quit方法调用时,Looper就会调用MessageQueue的quit或者quitSafely方法来通知消息队列退出,当消息队列标记为退出状态是,它的next方法就会返回null。

所以说Looper必须退出,否则loop就会一直循环下去。当loop方法去调用MessageQueue的next方法来获取新消息,而next是一个阻塞操作,当没有消息时,next方法会一直阻塞,导致loop方法一直阻塞在那里。有消息looper处理:msg.target.dispatchMessage(msg) ;msg.target是发送这条消息的Handler对象

1.2.4、Handler的工作原理

Handler的工作包括消息的发送和接收过程。发送可用post系列方法和send系列方法。(post最终通过send)。

Handler发送消息的过程仅仅是向消息队列中插入了一条消息,MessageQueue的next方法就会返回这条消息给Looper,Looper收到消息后就开始处理消息,最终消息由Looper交给Handler处理,即handler的dispatchMesage方法被调用

Handler处理消息的三个方式对应dispatchMesage方法的三个处理情况 :

1)handler.post(Runnable r)

2) handler = new Handler(callback)

3) 派生子类,重写handleMessage方法。

Handler还有一个特殊的构造方法,那就是通过特定的Looper来构造Handler

public   Handler (Looper looper){

           this(looper,null,false) ;

}

可以实现一些特殊的功能。

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