Esper's Blog - Android
type: channel
link: https://esperz.top/index.php/category/android/
description: Android编程相关
items: Android中的消息机制

Android中的消息机制
type: item
date: 2020-11-14T15:25:00+08:00
description: 简单码两句。 主要是解决了对于Android多线程机制默认操作的疑惑。 学过Android开发的大概大部分知道，Android的前台线程是UI线程。但是根据开发组的意图来看，这个线程应该是空闲率越高越好。如果学过计算机网络的话，这点可以很轻松的理解，越高的资源占用率意味着越大的延迟，只有当占用率尽可能低的时候，才能满足快速、及时响应的需求。 而多线程在解决了线程占用率问题（通过将大部分高时延的任务下放到后台线程完成，这些线程的响应实验要求相对较小）的同时，也带来了同步问题。Android解决同步问题的方法非常简单粗暴，“谁创建，谁拥有”。换个说法，只有创建线程不安全对象的线程本身才具有修改线程数据的权利。 那么，如果外界有修改线程不安全对象数据的需求的话，那么就必须由所有者线程主动提供一个入口，以所有者线程的身份对资源进行操作。Android为这个理论提供的时间就是Message, MessageQueue, Looper, Handler四件套。四件套的具体功能就不做赘述了，网上到处都是，而其中最为关键的，也是最常见到的组件之一，就是Handler。作为外部线程来说，调用Handler的各类message方法可以向所有者线程发送申请以修改资源；作为所有者线程来说，实现handleMessage方法可以从外部接收，并且自定义地处理请求。 然后困惑之处就在于，按照书上的方法，只要实现一个Handler类就能完成对这种资源的访问。四个组件既然是一套，那为什么只要四分之一就能完成功能呢？最重要的绑定线程的工作，又是在何处完成？ 带着这个疑问，去网上转了一圈，最后在官方文档找到了答案（ https://developer.android.com/reference/kotlin/android/os/Handler ）。其中的奥妙就在于，我们的确只需要实现Handler就行了，在Handler类实体化的时候，内部就定义了一系列的操作，包括创建四件套中除Message外的其他两件（Message在四件套中主要作为数据型，而非逻辑型组件，只用于传递Handler请求）。根据书上所说，Looper类的构造器甚至还是私有的，一看就是不希望别人去动的那种。在IDE中多按几次ctrl看看源码，就能发现Handler的无参构造器会调用Looper.myLooper()方法，继续刨的话可以看见，Looper对象已经被ThreadLocal作为线程私有变量保管得好好的了。 总而言之，在日常使用Android Handler的时候，只要实现这个类就行了，其他工作其实是已经由Android框架本身完成了的，放心大胆使用即可。