WindowManger詳解
更新
直播回放已放出,請戳連結食用:不使用Activity如何新增一個View
整體方案
在Service中通過WindowManger新增View的方式來把UI介面顯示出來
業務場景
具體場景
- IQOO手機,遊戲輔助
這種場景能否使用Activity方式來做
使用activity會對下層window產生阻塞,而使用WindowManager新增view的方式則不會阻塞
WindowManger簡介
WindowManger是普通App程式用來與系統服務(WindowMangerService)通訊的一個介面。
獲取WindowManger例項物件的方法是使用Context.getSystemService(Context.WINDOW_SERVICE
)
如何使用
- 新增許可權
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
複製程式碼
-
手動引導開啟
顯示在其他應用上層
-
獲取WindowManger並新增View
WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); //獲取系統服務
windowManager.addView(myView, p);
複製程式碼
- 不使用時移除View
WindowManager使用詳解
WindowManger
- 新增View :
addView()
注意 同一個window,只能新增一個View,新增多個View會報出以下異常
Caused by: java.lang.IllegalStateException: View android.widget.RelativeLayout{b3a2c6a V.E...... ......I. 0,0-0,0 #7f070081 app:id/rl_root} has already been added to the window manager.
複製程式碼
- 移除View :
remoview()
由於同一個View只能新增一個View,所以,要想在已新增View的Window中再新增View,必須先移除已新增的View
- 更新佈局屬性 :
updateViewLayout(view,params)
通過對第二個引數WindowManger.LayoutParams的屬性設定後,呼叫本方法才會使這些屬性生效
WindowManger.LayoutParms
WindowManger.LayoutParms
其實是ViewGrop.LayoutParms
的子類物件,所以View設定LayoutParams時可以直接設定
- 控制是否可以響應觸控事件
layoutParams.type
FLAG_NOT_TOUCHABLE
FLAG_NOT_TOUCH_MODAL
- 控制window的顯示層級
layoutParams.type
TYPE_TOAST
(Andorid 5.0及以下系統版本可規避許可權問題)TYPE_APPLICATION_WINOW
(應用層Winow等級)TYPE_PRIORTY_PHONE
(系統層Window等級)
- 控制view的顯示範圍
layoutParams.flags
FLAG_FULLSCREEN
FLAG_LAYOUT_IN_SCREEN
- 控制view的顯示位置
layoutParams.width
layoutParams.height
示例專案
還要注意哪些問題?
- 使用單獨程式,避免影響主業務功能
- 提升程式優先順序,避免被Kill
- 使用前臺服務
- 1畫素保活
- 繫結系統服務
提示:可通過oom_adj檢視某個程式的程式等級
- 要對服務被Kill後的重啟邏輯進行處理
原始碼淺析
由於時間關係,這裡我們只對相關原始碼進行一個簡單的介紹,先來看下相關的類
WindowManger
這個類,其實只是一個介面,用來溝通普通應用程式和系統服務WindowMangerservice
我們在上面的使用中也看到了,獲取WindowManger這個類的例項物件,是通過Context.getSystemServer(Context.WINDOW_SERICE)
獲取的
通過上面的UML類圖我們也可以看到,其實WindowManger是一個介面,而它的真正的例項物件是WindowMangerImpl
這個類
而WindowMangerImpl
又把具體的新增View的工作封裝到了WindowManagerGlobal
中來操作,這個類中又涉及到了另外一個重要的類--Display
,這個類主要是封裝了一些顯示相關的資訊,比如window的邏輯寬顯示資料(logical displays)和物理顯示資料(physical displays)
什麼是
logical displays
原始碼中對此解釋是,邏輯顯示不一定代表特定的物理顯示裝置,例如內建螢幕或外接顯示器。 邏輯上的內容根據裝置的不同,螢幕可以顯示在一個或多個物理螢幕上
什麼是
physical displays
就是Android裝置螢幕的真實的Displays資料,比如你的手機是4K的螢幕(physical displays),但是廠商為了進行一些優化工作(比如省電?)可以把顯示尺寸(logical displays)設定為1920* 1080
鄭重宣告
本文版權歸Android研習社
所有,未經允許禁止轉載,侵權必究!