在Android中,只有主線程才能更新UI纵穿,但是主線程不能進(jìn)行耗時(shí)操作,否則會(huì)產(chǎn)生ANR異常奢人,所以常常把耗時(shí)操作放到其他子線程進(jìn)行谓媒。如果在子線程中需要更新UI,一般都是通過(guò)Handler發(fā)送消息何乎,主線接收消息后進(jìn)行相應(yīng)的UI邏輯處理句惯。
一.什么是Handler
Handler是一個(gè)消息分發(fā)對(duì)象土辩。
Handler是Android系統(tǒng)提供的一套用來(lái)更新UI的機(jī)制,也是一套消息處理機(jī)制宗弯,可以通過(guò)Handler發(fā)消息脯燃,也可以通過(guò)Handler處理消息。
二.為什么使用Handler
為了解決多線程并發(fā)的問(wèn)題蒙保!
比如:如果在一個(gè)activity中有多個(gè)線程同時(shí)更新UI,并且沒(méi)有加鎖欲主,就會(huì)出現(xiàn)界面錯(cuò)亂的問(wèn)題邓厕。但是如果對(duì)這些更新UI的操作都加鎖處理,又會(huì)導(dǎo)致性能下降扁瓢。出于對(duì)性能問(wèn)題的考慮详恼,Android提供這一套使用Handler更新UI的機(jī)制,不用再去關(guān)心多線程的問(wèn)題引几,所有的更新UI的操作昧互,都是在主線程的消息隊(duì)列中去輪詢處理的。
在Android系統(tǒng)中伟桅,只有主線程才能更新UI敞掘,提到主線程,就不得說(shuō)一下ActivityThread楣铁,一個(gè)應(yīng)用內(nèi)部的邏輯處理都是在ActivityThread內(nèi)部依靠Handler來(lái)進(jìn)行處理的玖雁,比如:activity、service相關(guān)的創(chuàng)建等相關(guān)邏輯盖腕,在應(yīng)用創(chuàng)建后赫冬,會(huì)調(diào)用到ActivityThread內(nèi)部的main()方法,邏輯如下:
public static void main(String[] args) {
......
//創(chuàng)建Looper
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
//創(chuàng)建Handler
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
//開(kāi)啟loop()循環(huán)
Looper.loop();
}
從上面可以看到在ActivityThread里面的main()中溃列,執(zhí)行了Looper.prepareMainLooper()及Looper.loop()劲厌,接下來(lái)一起分析一下Android系統(tǒng)的消息處理機(jī)制。
三.源碼分析
Android內(nèi)部的消息處理機(jī)制主要是由Handler听隐、Looper补鼻、MessageQueue、Message來(lái)組成的遵绰,具體分工如下:
_Handler_:負(fù)責(zé)發(fā)送消息及處理消息
_Looper_:不斷的從消息隊(duì)列中取出消息辽幌,并且將消息給發(fā)送本條消息的Handler
_MessageQueue_:負(fù)責(zé)存儲(chǔ)消息
_Message_:消息本身,負(fù)責(zé)攜帶數(shù)據(jù)
1.Looper
Looper分為主線程和其他子線程椿访,前面講到乌企,主線程的Looper是在進(jìn)程啟動(dòng)后調(diào)用ActivityThread的main()里面通過(guò)prepareMainLooper()創(chuàng)建的:
a.prepareMainLooper()
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
prepareMainLooper()內(nèi)部會(huì)調(diào)用prepare(false)來(lái)進(jìn)行創(chuàng)建,且Looper是不能退出的成玫,然后對(duì)sMainLooper進(jìn)行賦值加酵;
b.prepare()
//只能通過(guò)Looper.prepare()方法去初始化一個(gè)Looper
public static void prepare() {
prepare(true);
}
//一個(gè)線程中只能有一個(gè)Looper對(duì)象拳喻,否則在第二次嘗試初始化Looper的時(shí)候,就會(huì)拋出異常
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));//創(chuàng)建了new Looper
}
子線程通過(guò)prepare()內(nèi)部調(diào)用prepare(true)來(lái)創(chuàng)建對(duì)應(yīng)的Looper猪腕,且Looper是可以退出的冗澈,為什么要退出,后面會(huì)講到陋葡;
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
private Looper(boolean quitAllowed) {
//創(chuàng)建Looper的時(shí)候會(huì)創(chuàng)建一個(gè)MessageQueue
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
Looper構(gòu)造方法內(nèi)會(huì)創(chuàng)建MessageQueue()亚亲,為后續(xù)消息處理做準(zhǔn)備,然后獲取到當(dāng)前的Thread賦值給mThread腐缤,后續(xù)通過(guò)getThread()可以獲取到當(dāng)前的thread捌归,可以用來(lái)判斷是否為主線程。
《Android Framework 開(kāi)發(fā)揭秘》
第一章 系統(tǒng)啟動(dòng)流程分析
- 第一節(jié) Android啟動(dòng)概覽
- 第二節(jié) init.rc解析
- 第三節(jié) Zygote
- 第四節(jié) 面試題
第二章 Binder解析
- 第一節(jié) 宏觀認(rèn)識(shí)Binder
- 第二節(jié)binder的jni方法注冊(cè)
- 第三節(jié)binder驅(qū)動(dòng)
- 第四節(jié) 數(shù)據(jù)結(jié)構(gòu)
- 第五節(jié) 啟動(dòng)service_manager
- 第六節(jié)獲取service_manager
- 第七節(jié) addService流程
- 第八節(jié) Binder面試題全解析
第三章 Handler解析
- 第一節(jié) 源碼分析
- 第二節(jié) 難點(diǎn)問(wèn)題
- 第三節(jié)Handler常問(wèn)面試題
第四章 AMS 解析
- 第一節(jié) 引言
- 第二節(jié) Android架構(gòu)
- 第三節(jié) 通信方式
- 第四節(jié) 系統(tǒng)啟動(dòng)系列
- 第五節(jié) AMS
- 第六節(jié) AMS 面試題解析
第五章 WMS解析
- 第一節(jié)Activity與Window相關(guān)概念
- 第二節(jié) Android窗口管理服務(wù)WindowManagerService計(jì)算Activity窗口大小的過(guò)程分析
- 第三節(jié)Android窗口管理服務(wù)WindowManagerService對(duì)窗口的組織方式分析
- 第四節(jié) Android窗口管理服務(wù)WindowManagerService對(duì)輸入法窗口的管理分析
- 第五節(jié) Android窗口管理服務(wù)WindowManagerService對(duì)壁紙窗口的管理分析
- ......
第六章PKMS Android10.0 源碼解讀
- 第一節(jié) 前言 PKMS 是什么東西岭粤?
- 第二節(jié) PKMS 概述信息
- 第三節(jié) PKMS角色位置
- 第四節(jié) PKMS 啟動(dòng)過(guò)程分析
- 第五節(jié) APK的掃描
- 第七節(jié) PMS之權(quán)限掃描
- 第八節(jié) PackageManagerService大綜合筆記
更多的Android可以查看我的個(gè)人介紹O鳌!剃浇!