網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
詳解Android創(chuàng)建Handler的必備知識(shí)點(diǎn)_Android
作者:長(zhǎng)安皈故里 ? 更新時(shí)間: 2022-11-23 編程語(yǔ)言普通Handler創(chuàng)建
一般下面這樣創(chuàng)建Handler
時(shí)AS會(huì)進(jìn)行告警:
刪除線提示Handler
的無(wú)參構(gòu)造方法已經(jīng)被@Deprecated
標(biāo)記,正確的做法都是使用帶Looper
構(gòu)造參數(shù)的構(gòu)造方法進(jìn)行Handler
的創(chuàng)建:
這樣做的好處是直接指定消息調(diào)度在哪個(gè)Looper
,而Looper
是通過(guò)ThreadLocal
和線程綁定在一起,也就是說(shuō),指明了Looper
就能知道當(dāng)前消息Message
最終會(huì)在哪個(gè)線程中執(zhí)行。
而之所以Handler
無(wú)參構(gòu)造方法被廢棄的一個(gè)原因就是:
它會(huì)嘗試從當(dāng)前線程中的ThreadLocal
獲取Looper
,主線程會(huì)自動(dòng)幫助我們創(chuàng)建好Looper
自然是沒(méi)什么問(wèn)題,但是如果子線程中執(zhí)行Handler
的創(chuàng)建,而沒(méi)有手動(dòng)調(diào)用Looper.prepare()
,就會(huì)導(dǎo)致崩潰。
異步Handler的使用及創(chuàng)建
異步Handler
有什么作用呢,相比較于普通Handler
,可以獲取優(yōu)先調(diào)度執(zhí)行權(quán),當(dāng)前,前提是要添加同步屏障消息。
這里解釋下同步屏障消息:
同步屏障消息和普通的Message
基本上沒(méi)啥區(qū)別,主要的一個(gè)區(qū)分點(diǎn)是同步屏障消息Message
的target
屬性為null,當(dāng)從消息隊(duì)列中取出消息并執(zhí)行時(shí),會(huì)先判斷下當(dāng)前的Message的
target是否為null,如果為null則會(huì)從消息隊(duì)列中優(yōu)先獲取異步消息 進(jìn)行調(diào)度執(zhí)行。
相應(yīng)的源碼如下:
添加消息屏障的方法為MessageQueue.postSyncBarrier()
,不過(guò)這個(gè)方法目前是不支持業(yè)務(wù)方直接進(jìn)行調(diào)用。
上面消息屏障說(shuō)完了,我們接下來(lái)看下異步消息如何創(chuàng)建:異步消息的創(chuàng)建依賴異步Hanlder
的創(chuàng)建。所以我們看下異步Handler
如何進(jìn)行創(chuàng)建:
@NonNull public static Handler createAsync(@NonNull Looper looper) { if (looper == null) throw new NullPointerException("looper must not be null"); return new Handler(looper, null, true); } @NonNull public static Handler createAsync(@NonNull Looper looper, @NonNull Callback callback) { if (looper == null) throw new NullPointerException("looper must not be null"); if (callback == null) throw new NullPointerException("callback must not be null"); return new Handler(looper, callback, true); }
Handler
提供了createAsync()
兩個(gè)重載方法進(jìn)行創(chuàng)建,最終會(huì)將Handler
的mAsynchronous
屬性置為true
,然后通過(guò)Hanlder
發(fā)送消息時(shí),最終會(huì)走到Handler.enqueueMessage()
方法:
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg, long uptimeMillis) { ... if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }
可以看到,如果mAsynchronous
屬性為true,就將Message
添加FLAG_ASYNCHRONOUS
置為異步消息。不過(guò)這個(gè)API是只有在SDK>=28以上才能調(diào)用,那么消息28的版本如何創(chuàng)建的,這里給出一個(gè)非常全面的兼容各個(gè)SDK版本的創(chuàng)建異步Handler的方法:
上面的使用講完了,說(shuō)下應(yīng)用了。這個(gè)異步消息+消息屏障在系統(tǒng)源碼中有一個(gè)非常典型的應(yīng)用場(chǎng)景,那就是界面的繪制:
由于界面的繪制渲染優(yōu)先級(jí)是比較高的,所以添加消息屏障后,將繪制相關(guān)的Message
指定為異步方式,就可以優(yōu)先進(jìn)行執(zhí)行。
原文鏈接:https://juejin.cn/post/7152294189932216327
相關(guān)推薦
- 2022-05-26 flutter底部彈出BottomSheet詳解_Android
- 2022-04-24 python使用技巧-文件讀寫(xiě)_python
- 2024-04-05 mybatis(mybatis-plus)報(bào)invalid bound statement (not
- 2022-04-04 webpack-插件: plugin的使用(clean-webpack-plugin)
- 2022-09-18 iOS?xcconfig編寫(xiě)示例教程_IOS
- 2024-03-20 mybatis-plus不同類型多源數(shù)據(jù)庫(kù)分頁(yè)攔截器配置
- 2023-04-03 Python數(shù)據(jù)結(jié)構(gòu)棧實(shí)現(xiàn)進(jìn)制轉(zhuǎn)換簡(jiǎn)單示例_python
- 2023-07-29 git如何配置多個(gè)SSH
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支