| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> Android消息机制 -> 正文阅读 |
|
[移动开发]Android消息机制 |
Android消息机制其实指的就是Handler的消息机制。 以上模型的解释: ?? ?1.以Handler的sendMessage方法为例,当发送一个消息后,会将此消息加入消息队列MessageQueue中。 ?? ?2.Looper负责去遍历消息队列并且将队列中的消息分发给对应的Handler进行处理。 ?? ?3.在Handler的handleMessage方法中处理该消息,这就完成了一个消息的发送和处理过程。 这里从图中可以看到参与消息处理有四个对象,它们分别是 Handler, Message, MessageQueue,Looper。 ThreadLocal 是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后,只有再指定线程中可以获取到存储的数据,对于其他线程来说则无法获取到数据。 我们看下ThreadLocal是如何存储数据的:
在源码里面我们可以看出 ThreadLocal在存储数据的时候,会先拿到当前线程,然后根据当前线程会拿到一个叫做ThreadLocalMap 的Map数组; 那么ThreadLocalMap 又是什么呢? 我们可以看到在CreateMap 里面是创建了ThreadLocalMap ,并且把我们当前线程当作Key,传递过去的? Value就是我们在调用ThreadLocal.set(T)传过来的值
?ThreadLocal是如何获取数据的
通过以上代码我们可以看出ThreadLocal是如何保证数据存储以后,只有再指定线程中可以获取到存储的数据,对于其他线程来说则无法获取到数据的了。 我们如何保证Acticity的默认线程是主线程的呢 在Acticity? 中我们用到的线程是ActivityThread这个线程,在这个线程的 main(String[] args)方法里面我们可以看到下面代码
//上面的代码里面我们可以看到创建??ActivityThread的??Looper.prepareMainLooper();???Looper.loop();? 保证了?ActivityThread为主线程。 创建全局唯一Looper对象和全局唯一MessageQueue消息对象 Activity中创建Handler 消息发送 消息处理? 消息阻塞和延时 Looper 的阻塞主要是靠 MessageQueue 来实现的,在next()@MessageQuese 进行阻塞,在 enqueueMessage()@MessageQueue 进行唤醒。主要依赖 native 层的 Looper 依靠 epoll 机制进行的。?
阻塞和延时,主要是next()中nativePollOnce(ptr, nextPollTimeoutMillis)调用naive方法操作管道,由nextPollTimeoutMillis决定是否需要阻塞nextPollTimeoutMillis为0的时候表示不阻塞,为-1的时候表示一直阻塞直到被唤醒,其他时间表示延时。 唤醒 主要是指enqueueMessage()@MessageQueue 进行唤醒。
简单理解阻塞和唤醒 就是在主线程的MessageQueue没有消息时,便阻塞在loop的queue.next()中的nativePollOnce()方法里,此时主线程会释放CPU资源进入休眠状态,直到下个消息到达或者有事务发生,通过往pipe管道写端写入数据来唤醒主线程工作。 这里采用的epoll机制,是一种IO多路复用机制,可以同时监控多个描述符,当某个描述符就绪(读或写就绪),则立刻通知相应程序进行读或写操作,本质同步I/O,即读写是阻塞的。 所以说,主线程大多数时候都是处于休眠状态,并不会消耗大量CPU资源。 从阻塞到唤醒,消息切换 延时入队 主要指enqueueMessage()消息入列是,上图代码对message对象池得重新排序,遵循规则(when从小到大)。 此处for死循环推出情况分两种 第一种:p==null表示对象池中已经运行到了最后一个,无需再循环。 第二种:碰到下一个消息when小于前一个,立马推出循环(不管对象池中所有message是否遍历完),进行从新排序。 |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/28 12:08:27- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |