網站首頁 編程語言 正文
Message的創建
消息Message
一般不支持大家直接通過new
的方式進行創建的,因為Message
作為Android系統中使用頻率非常高的一個對象,如果每次都泛濫的直接創建一個新的,對性能是有一定影響的,而通過對象池的方式進行復用 ,則是非常好的一種方式。
Message
中就提供了這樣的一個對象池(最大緩存消息數量為50):
通過鏈表的形式將一個個待復用的緩存Message
連接起來。并且提供了obtain()
方法負責從對象池中獲取一個Message
:
public static Message obtain() { synchronized (sPoolSync) { if (sPool != null) { Message m = sPool; sPool = m.next; m.next = null; m.flags = 0; // clear in-use flag sPoolSize--; return m; } } return new Message(); }
當消息調度完畢時,會通過recycleUnchecked()
方法進行回收并放入到對象池:
void recycleUnchecked() { flags = FLAG_IN_USE; what = 0; arg1 = 0; arg2 = 0; obj = null; ... synchronized (sPoolSync) { if (sPoolSize < MAX_POOL_SIZE) { next = sPool; sPool = this; sPoolSize++; } } }
重置要回收的Message
的各個成員屬性,然后添加到對象池sPool
。
消息分發執行的三種方式
消息調度分發最終是在Looper.loopOnce()
中執行,我們看下源碼:
private static boolean loopOnce(final Looper me, final long ident, final int thresholdOverride) { Message msg = me.mQueue.next(); // might block if (msg == null) { return false; } try { msg.target.dispatchMessage(msg); } msg.recycleUnchecked(); return true; }
核心就是msg.target.dispatchMessage()
,我們看下具體的方法邏輯:
public void dispatchMessage(@NonNull Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
源碼一目了然,接下來我們一個個的進行分析:
- 先檢測
Message
的callback
是否為null,不為null就執行callback
的run
方法調度執行,這個一般是如何傳入的呢:
public final boolean post(@NonNull Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); } private static Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; }
很熟悉的post()
方法就并不再過多介紹了。
- 然后檢測
Hander
的mCallback
是否為null,不為null就執行mCallback.handleMessage()
,這個是什么時候傳入的呢:
public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) { mLooper = looper; mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; }
通過Handler
構造方法時作為構造參數傳入,可以選擇性使用。
- 上面都不滿足,就調用
Handler
自身的handleMessage()
方法調度執行,這也是我們常用的消息執行的一種方式,一般都是創建Handler
對象時重寫這個該方法:
fun test333() { val handler = object : Handler(Looper.getMainLooper()) { override fun handleMessage(msg: Message) { super.handleMessage(msg) } } }
以上三種消息分發方式第一種和第三種使用的頻率比較高,第二種這種方式可以作為一種hook的手段攔截某些消息的原本調度邏輯,實現功能增強。
比如Activity、Service
等組件的調度是通過ApplicationThread
通過Handler
分發到主線程進行調度執行,如果你想監聽其生命周期,就可以通過上面的第二種方式結合反射給負責分發的Handler
注入一個mCallback
屬性值。
總結
本篇文章主要是介紹了Message
創建的正確方式,以及其如何在Handler
中調度分發的,每個流程是什么,希望能給你帶來幫助。
原文鏈接:https://juejin.cn/post/7151929832698281991
相關推薦
- 2022-04-12 python?獲取list?長度_python
- 2022-09-13 iOS實現手動和自動屏幕旋轉_IOS
- 2022-10-15 Qt?TCP網絡通信學習_C 語言
- 2022-05-06 C#迭代器方法介紹_C#教程
- 2022-12-23 iOS之異常與信號使用場景分析_IOS
- 2022-05-23 如何使Python中的print()語句運行結果不換行_python
- 2022-06-08 問題記錄:HttpServletRequestWrapper導致跨域失敗的問題
- 2022-06-08 報錯:No fallback instance of type class**解決辦法
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支