Android开发-Handler消息机制记录
背景
Handler在Android中非常重要,它可以实现线程之间的通信,Android中对于UI的更新只能在主线程中进行,所以Handler的地位非常重要,包括可以处理一些多个线程同时更新UI时的操作,Handler就是为了解决线程间通信而出现的。
Handler的使用
Handler和MessageQueue, Looper, Message共同构成一个消息处理机制,如下是Handler基本使用代码示例
// 创建Handler对象,获取主线程Looper
val mHandler = object : Handler(Looper.getMainLooper()) {override fun handleMessage(msg: Message) {when (msg.what) {1 -> {// 处理消息}}}}// 其他线程需要通知时调用sendMessage发消息通知目标线程thread { val msg = Message()msg.what = 1mHandler.sendMessage(msg)}
接下来解析下Handler消息处理机制的每一个组成部分的作用
- Handler: 用于消息的发送和处理
- Message: 携带消息的内容,参数有what、arg1、arg2(储存整型数据)、obj(储存对象类型)
- MessageQueue: 管理消息的队列,每个线程拥有一个
- Looper: 每个线程都有一个自己的Looper,管理MessageQueue,不断的循环从消息队列中取出消息并分发给相应的Handler
Handler原理
Handler机制过程
- 发送消息:需要通信的线程创建一个Handler对象用于发送消息传递信息,通过调用Handler的发送消息的方法来发送Message到MessageQueue,根据Handler源码可以发现如下发送消息的方法:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//public class Handler {...public final boolean post(@NonNull Runnable r) {throw new RuntimeException("Stub!");}public final boolean postAtFrontOfQueue(@NonNull Runnable r) {throw new RuntimeException("Stub!");}public final boolean postAtTime(@NonNull Runnable r, @Nullable Object token, long uptimeMillis) {throw new RuntimeException("Stub!");}public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) {throw new RuntimeException("Stub!");}public final boolean postDelayed(@NonNull Runnable r, @Nullable Object token, long delayMillis) {throw new RuntimeException("Stub!");}public final boolean postDelayed(@NonNull Runnable r, long delayMillis) {throw new RuntimeException("Stub!");}public final boolean sendEmptyMessage(int what) {throw new RuntimeException("Stub!");}public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {throw new RuntimeException("Stub!");}public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {throw new RuntimeException("Stub!");}public final boolean sendMessage(@NonNull Message msg) {throw new RuntimeException("Stub!");}public final boolean sendMessageAtFrontOfQueue(@NonNull Message msg) {throw new RuntimeException("Stub!");}public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {throw new RuntimeException("Stub!");}public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {throw new RuntimeException("Stub!");}
}
可以发现以上源码中post开头的方法都有一个Runnable参数,所以使用post传递信息时,当Handler从队列取出一个Message后执行到dispatchMessage()方法进行分发时会自动处理post中的自定义Runnable,而不会去执行Handler中重写的handleMessage方法
同理,send开头的方法可以将数据封装到Bundle中绑定到Message或者设置msg.what的值来进行区分然后分发到对应传入的回调接口的handleMessage方法中处理(需要先在接收的线程中实现一个Handler类然后重写下handleMessage方法)
- Looper事件循环:在线程中先调用Looper.prepare(),然后通过Looper.loop()让线程开始循环处理消息,如果一段时间后如果不需要了也可以调用Looper.end()结束当前所在线程的循环器,可以通过Looper.myQueue()获取到线程中的MessageQueue
- 处理消息:需要接收通信的线程创建一个Handler对象用于接收信息,创建Handler对象后需要重写handleMessage()方法来处理其他线程获取到的信息并进行相应操作处理
源码解析
Handler源码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package android.os;import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.Printer;public class Handler {/** @deprecated */@Deprecatedpublic Handler() {throw new RuntimeException("Stub!");}/** @deprecated */@Deprecatedpublic Handler(@Nullable Callback callback) {throw new RuntimeException("Stub!");}public Handler(@NonNull Looper looper) {throw new RuntimeException("Stub!");}public Handler(@NonNull Looper looper, @Nullable Callback callback) {throw new RuntimeException("Stub!");}@NonNullpublic static Handler createAsync(@NonNull Looper looper) {throw new RuntimeException("Stub!");}@NonNullpublic static Handler createAsync(@NonNull Looper looper, @NonNull Callback callback) {throw new RuntimeException("Stub!");}public void dispatchMessage(@NonNull Message msg) {throw new RuntimeException("Stub!");}public final void dump(@NonNull Printer pw, @NonNull String prefix) {throw new RuntimeException("Stub!");}@NonNullpublic final Looper getLooper() {throw new RuntimeException("Stub!");}@NonNullpublic String getMessageName(@NonNull Message message) {throw new RuntimeException("Stub!");}public void handleMessage(@NonNull Message msg) {throw new RuntimeException("Stub!");}public final boolean hasCallbacks(@NonNull Runnable r) {throw new RuntimeException("Stub!");}public final boolean hasMessages(int what) {throw new RuntimeException("Stub!");}public final boolean hasMessages(int what, @Nullable Object object) {throw new RuntimeException("Stub!");}@NonNullpublic final Message obtainMessage() {throw new RuntimeException("Stub!");}@NonNullpublic final Message obtainMessage(int what) {throw new RuntimeException("Stub!");}@NonNullpublic final Message obtainMessage(int what, int arg1, int arg2) {throw new RuntimeException("Stub!");}@NonNullpublic final Message obtainMessage(int what, int arg1, int arg2, @Nullable Object obj) {throw new RuntimeException("Stub!");}@NonNullpublic final Message obtainMessage(int what, @Nullable Object obj) {throw new RuntimeException("Stub!");}public final boolean post(@NonNull Runnable r) {throw new RuntimeException("Stub!");}public final boolean postAtFrontOfQueue(@NonNull Runnable r) {throw new RuntimeException("Stub!");}public final boolean postAtTime(@NonNull Runnable r, @Nullable Object token, long uptimeMillis) {throw new RuntimeException("Stub!");}public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) {throw new RuntimeException("Stub!");}public final boolean postDelayed(@NonNull Runnable r, @Nullable Object token, long delayMillis) {throw new RuntimeException("Stub!");}public final boolean postDelayed(@NonNull Runnable r, long delayMillis) {throw new RuntimeException("Stub!");}public final void removeCallbacks(@NonNull Runnable r) {throw new RuntimeException("Stub!");}public final void removeCallbacks(@NonNull Runnable r, @Nullable Object token) {throw new RuntimeException("Stub!");}public final void removeCallbacksAndMessages(@Nullable Object token) {throw new RuntimeException("Stub!");}public final void removeMessages(int what) {throw new RuntimeException("Stub!");}public final void removeMessages(int what, @Nullable Object object) {throw new RuntimeException("Stub!");}public final boolean sendEmptyMessage(int what) {throw new RuntimeException("Stub!");}public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {throw new RuntimeException("Stub!");}public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {throw new RuntimeException("Stub!");}public final boolean sendMessage(@NonNull Message msg) {throw new RuntimeException("Stub!");}public final boolean sendMessageAtFrontOfQueue(@NonNull Message msg) {throw new RuntimeException("Stub!");}public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {throw new RuntimeException("Stub!");}public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {throw new RuntimeException("Stub!");}public String toString() {throw new RuntimeException("Stub!");}public interface Callback {boolean handleMessage(@NonNull Message var1);}
}