網(wǎng)站開發(fā)規(guī)劃書百度人工優(yōu)化
作者:bobby_developer
1. WMS原理:WMS角色與實(shí)例化過程
-
window:它是一個(gè)抽象類,具體實(shí)現(xiàn)類為 PhoneWindow ,它對 View 進(jìn)行管理。Window是View的容器,View是Window的具體表現(xiàn)內(nèi)容;
-
windowManager:是一個(gè)接口類,繼承自接口 ViewManager ,從它的名稱就知道它是用來管理 Window 的,它的實(shí)現(xiàn)類為 WindowManagerImpl;
-
WMS:是窗口的管理者,它負(fù)責(zé)窗口的啟動(dòng)、添加和刪除。另外窗口的大小和層級也是由它進(jìn)行管理的;
SystemServer啟動(dòng)WMS流程表:
1.1 window
1.2 顯示層級
1.3 窗口標(biāo)志位
1.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON(當(dāng)Window可見時(shí)允許鎖屏)
2.FLAG_NOT_FOCUSABLE(Window 不能獲得輸入焦點(diǎn),即不接受任何按鍵或按鈕事件,例如該 Window 上 有 EditView,點(diǎn)擊 EditView 是 不會(huì)彈出軟鍵盤的,Window 范圍外的事件依舊為原窗口處理;例如點(diǎn)擊該窗口外的view,依然會(huì)有響應(yīng)。另外只要設(shè)置了此Flag,都將會(huì)啟用FLAG_NOT_TOUCH_MODAL) 3.FLAG_NOT_TOUCH_MODAL(設(shè)置了該 Flag,將 Window 之外的按鍵事件發(fā)送給后面的 Window 處理, 而自己只會(huì)處理 Window 區(qū)域內(nèi)的觸摸事件;Window 之外的 view 也是可以響應(yīng) touch 事件。 4.FLAG_NOT_TOUCHABLE(設(shè)置了該Flag,表示該 Window 將不會(huì)接受任何 touch 事件,例如點(diǎn)擊該 Window 不會(huì)有響應(yīng),只會(huì)傳給下面有聚焦的窗口) 5.FLAG_KEEP_SCREEN_ON(只要 Window 可見時(shí)屏幕就會(huì)一直亮著,視頻播放、游戲) 6.FLAG_LAYOUT_NO_LIMITS(允許 Window 超過屏幕之外)
7.FLAG_IGNORE_CHEEK_PRESSES(當(dāng)用戶的臉貼近屏幕時(shí)(比如打電話),不會(huì)去響應(yīng)此事件 )
8.FLAG_SHOW_WHEN_LOCKED(當(dāng)用戶的臉貼近屏幕時(shí)(比如打電話),不會(huì)去響應(yīng)此事件
9.FLAG_IGNORE_CHEEK_PRESSES ; 窗口可以在鎖屏的 Window 之上顯示, 使用Activity#setShowWhenLocked(boolean) 方法代替)
1.4 WindowManager
在了解WindowManager管理View實(shí)現(xiàn)之前,先了解下WindowManager相關(guān)類圖以及Activity界面各層級顯示關(guān)系;
2. WMS工作原理
2.1 WMS職責(zé)
2.2 WMS中重要的一些屬性釋義
2.3 AddWindow源碼分析
WMS中addWindow源碼分析,在分析addWindow之前,先了解幾個(gè)類;
-
WindowToken
WindowToken具有令牌的作用,是對應(yīng)用組件的行為進(jìn)行規(guī)范管理的一個(gè)手段。WindowToken由應(yīng)用組件或其管理者負(fù)責(zé)向WMS聲明并持有。應(yīng)用組件在需要新的窗口時(shí),必須提供WindowToken以表明自己的身份,并且窗口的類型必須與所持有的WindowToken的類型一致,同時(shí)它將屬于同一個(gè)應(yīng)用組件的窗口組織在了一起;
-
DisplayContent
如果說WindowToken按照窗口之間的邏輯關(guān)系將其分組,那么DisplayContent則根據(jù)窗口的顯示位置將其分組。隸屬于同一個(gè)DisplayContent的窗口將會(huì)被顯示在同一個(gè)屏幕中。每一個(gè)DisplayContent都對應(yīng)這一個(gè)唯一的ID,在添加窗口時(shí)可以通過指定這個(gè)ID決定其將被顯示在那個(gè)屏幕中。DisplayContent是一個(gè)非常具有隔離性的一個(gè)概念。處于不同DisplayContent的兩個(gè)窗口在布局、顯示順序以及動(dòng)畫處理上不會(huì)產(chǎn)生任何耦合。因此,就這幾個(gè)方面來說,DisplayContent就像一個(gè)孤島,所有這些操作都可以在其內(nèi)部獨(dú)立執(zhí)行。因此,這些本來屬于整個(gè)WMS全局性的操作,變成了DisplayContent內(nèi)部的操作了。
-
WindowState 表示一個(gè)窗口的所有屬性,所以它是WMS中事實(shí)上的窗口;當(dāng)向WMS添加一個(gè)窗口時(shí),WMS會(huì)為其創(chuàng)建一個(gè)WindowState。另外WMS.addWindow()函數(shù)中看到新的WindowState被保存到mWindowMap中,鍵值為IWindow的Bp端。mWindowMap是整個(gè)系統(tǒng)所有窗口的一個(gè)全集。
2.4 removeWindow
void removeWindow(Session session, IWindow client) {synchronized (mGlobalLock) {//獲取WindowStateWindowState win = windowForClientLocked(session, client, false);if (win != null) {//執(zhí)行刪除win.removeIfPossible();return;}// Remove embedded window map if the token belongs to an embedded windowmEmbeddedWindowController.remove(client);}}
win.removeIfPossible方法和它的名字一樣, 并不是直接執(zhí)行刪除操作,而是進(jìn)行多個(gè)條件判斷過濾,滿足其中一個(gè)條件就會(huì)return,推遲刪除操作。比如View正在運(yùn)行一個(gè)動(dòng)畫,這是就會(huì)推遲刪除操作直到動(dòng)畫完成。然后調(diào)用removeImmediately方法。
3. 事件派發(fā)
EventHub:
1.使用inotify監(jiān)聽輸入設(shè)備的添加和移除;
2.使用epoll機(jī)制監(jiān)聽輸入設(shè)備的數(shù)據(jù)變化;
3.讀取設(shè)備文件數(shù)據(jù);
4.將原始數(shù)據(jù)返回給InputReader;
InputReader:不斷讀取由EventHub監(jiān)聽到的input事件,將多個(gè)事件組合成一個(gè)可供上層消費(fèi)的事件(比如將一組觸摸事件合并成一個(gè)action_down事件),然后交給InputDispatcher進(jìn)行事件分發(fā);
InputDispatcher:拿到InputReader獲取的事件后,對事件進(jìn)行包裝,尋找并分發(fā)到目標(biāo)窗口,對應(yīng)inputChannel輸入;
Android系統(tǒng)是由事件驅(qū)動(dòng)的,而input是常見的事件之一,點(diǎn)擊、滑動(dòng)、長按等操作,都屬于input事件,核心類就是InputReader和InputDispatcher;
解釋: ViewRootImpl#WindowInputEventReceiver:從下面源碼可以看出,此類用于InputChannel輸入事件接收以及處理輸入事件分發(fā);
final class WindowInputEventReceiver extends InputEventReceiver {//構(gòu)造方法,接受inputchannel輸入事件public WindowInputEventReceiver(InputChannel inputChannel, Looper looper) {super(inputChannel, looper);}@Overridepublic void onInputEvent(InputEvent event) {...if (processedEvents != null) {if (processedEvents.isEmpty()) {// InputEvent consumed by mInputCompatProcessorfinishInputEvent(event, true);} else {for (int i = 0; i < processedEvents.size(); i++) {//對輸入事件進(jìn)行分發(fā)enqueueInputEvent(processedEvents.get(i), this,QueuedInputEvent.FLAG_MODIFIED_FOR_COMPATIBILITY, true);}}} else {enqueueInputEvent(event, this, 0, true);}}
ViewRootImpl#InputStage:抽象類,主要用來將事件的處理分成若干個(gè)階段(stage)進(jìn)行,如果該事件沒有被處理,則該stage就會(huì)調(diào)用onProcess方法處理,然后調(diào)用forward執(zhí)行下一個(gè)stage的處理;如果該事件被標(biāo)識為處理則直接調(diào)用forward,執(zhí)行下一個(gè)stage的處理,直到?jīng)]有下一個(gè)stage;
ViewPostImeInputStage:InputStage的子類,將輸入事件傳遞到上層視圖;至此,輸入事件一層層向上傳遞,最終交由具體的view進(jìn)行處理;
如果你還沒有掌握Framework,現(xiàn)在想要在最短的時(shí)間里吃透它,可以參考一下《Android Framework核心知識點(diǎn)》,里面內(nèi)容包含了:Init、Zygote、SystemServer、Binder、Handler、AMS、PMS、Launcher……等知識點(diǎn)記錄。
《Framework 核心知識點(diǎn)匯總手冊》:https://qr18.cn/AQpN4J
Handler 機(jī)制實(shí)現(xiàn)原理部分:
1.宏觀理論分析與Message源碼分析
2.MessageQueue的源碼分析
3.Looper的源碼分析
4.handler的源碼分析
5.總結(jié)
Binder 原理:
1.學(xué)習(xí)Binder前必須要了解的知識點(diǎn)
2.ServiceManager中的Binder機(jī)制
3.系統(tǒng)服務(wù)的注冊過程
4.ServiceManager的啟動(dòng)過程
5.系統(tǒng)服務(wù)的獲取過程
6.Java Binder的初始化
7.Java Binder中系統(tǒng)服務(wù)的注冊過程
Zygote :
- Android系統(tǒng)的啟動(dòng)過程及Zygote的啟動(dòng)過程
- 應(yīng)用進(jìn)程的啟動(dòng)過程
AMS源碼分析?:
- Activity生命周期管理
- onActivityResult執(zhí)行過程
- AMS中Activity棧管理詳解
深入PMS源碼:
1.PMS的啟動(dòng)過程和執(zhí)行流程
2.APK的安裝和卸載源碼分析
3.PMS中intent-filter的匹配架構(gòu)
WMS:
1.WMS的誕生
2.WMS的重要成員和Window的添加過程
3.Window的刪除過程
《Android Framework學(xué)習(xí)手冊》:https://qr18.cn/AQpN4J
- 開機(jī)Init 進(jìn)程
- 開機(jī)啟動(dòng) Zygote 進(jìn)程
- 開機(jī)啟動(dòng) SystemServer 進(jìn)程
- Binder 驅(qū)動(dòng)
- AMS 的啟動(dòng)過程
- PMS 的啟動(dòng)過程
- Launcher 的啟動(dòng)過程
- Android 四大組件
- Android 系統(tǒng)服務(wù) - Input 事件的分發(fā)過程
- Android 底層渲染 - 屏幕刷新機(jī)制源碼分析
- Android 源碼分析實(shí)戰(zhàn)