《Android開發藝術探索》讀書筆記--第8章 理解Window和WindowManager

  1. Window 表示一個窗口的概念,是一個抽象類,具體實現是 PhoneWindow,通過 WindowManager 創建,WindowManager 是外界訪問 Window 的入口,Window 具體實現位於 WindowManagerService 中,WindowManager 和 WindowManagerService 交互是IPC過程,所有視圖都是通過 Window 呈現的,Window是 View 的直接管理者。

8.1 Window和WindowManager

Button button = new Button(this);
button.setText("button");
WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT, 0, 0,
                PixelFormat.TRANSPARENT);
//window 顯示特性
//FLAG_NOT_FOCUSABLE 不能獲取焦點
//FLAG_NOT_TOUCH_MODAL 將意外點擊事件,傳遞給底層Window
//FLAG_SHOW_WHEN_LOCKED 顯示在鎖屏界面上              
params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
params.gravity = Gravity.LEFT | Gravity.TOP;
params.x = 100;
params.y = 300;
WindowManager windowManager = getWindowManager();
windowManager.addView(button, params);
  1. Window 三種類型
類型 簡介 層級
應用Window 對應一個Activity 1-99
子Window Dialog等 1000-1999
系統Window 需要權限,比如 Toast和系統狀態欄 2000-2999
  1. 一般使用
params = LayoutParams.TYPE_SYSTEM_ERROR
<user-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"
  1. 提供功能
public interface ViewManager
{
   addView();
   updateViewLayout();
   removeView();
}

8.2 Window 的內部機制

  1. Window 對應一個 View 和一個 ViewRootImpl,Window 和 View 通過 ViewRootImpl 來建立聯繫。

8.2.1 Window 的添加過程

  1. 通過 WindowManager 的 addView 來實現,WindowManager 是一個接口,真正實現通過 WindowManagerImpl 類(WindowManagerGlobal–使用橋接模式)。
  2. addView 過程
1.檢查參數合法,子 Window 還需要調整佈局參數
2.創建 ViewRootImpl並將View添加到列表中
3.通過 ViewRootImpl 來更新界面並且完成 Window的添加過程(IPC 調用) 

ViewRootImpl(setView) -> requestLayout(scheduleTraversals)-> WindowSession(是IWindowSession,一個 Binder對象,真正實現 Session,添加過程是一次 IPC 調用過程)
  1. removeView 過程
WindowManagerGlobal->removeView(findViewLocked)->ViewRootImpl來完成刪除操作。
1.removeView 異步刪除 die 方法 並沒有馬上刪除,添加到 mDyingViews 中
2.removeViewImmediate 同步刪除
3.刪除邏輯 dispatchDetacheFromWindow 中
3.1.垃圾回收,清除數據、回調
3.2.Session的remove刪除Window,IPC 過程
3.3.View 的 dispatchDetachedFromWindow,資源回收(終止動畫、停止線程)
3.4.WindowManagerGlobal的doRemoveView 方法刷新數據。
  1. updateViewLayout 過程
WindowManagerGlobal->updateViewLayout()
1.更新 View 的 LayoutParams 替換老的 LayoutParams
2.更新 ViewRootImpl中的 LayoutParams(setLayoutParams)
3.sheduleTracersals 對View 重新佈局(測量、佈局、繪製)
4.WindowSession更新Window視圖
5.WMS的relayoutWindow具體實現,IPC 過程。

8.3 Window 創建過程

  1. View 是 Android 中視圖呈現方式,不能單獨存在,必須依附 Window上。

8.3.1 Activity 的 Window 創建過程

  1. Activity啓動過程 最終由 ActivityThread 中的 performLauncherActivity() 來完成(通過類加載器來創建 Activity 實例對象,並調用 attach 方法關聯運行過程中依賴的上下文環境變量)。
1.Activity中的 attach中,創建 Window對象(PolicyManager的makeNewWindow->new PhoneWindow()),並且設置回調。
2.setContentView->getWindow().setContentView()
3.步驟
3.1.如果沒有 DecorView,就創建
3.2.將View添加到DecorView的mContentParent中
3.3.回調Activity的onContentChanged方法通知Activity視圖發生改變。
3.4.ActivityThread的handleResumeActivity會調用Activity的onResume,調用 makeViesible(),DecorView 顯示出來了

8.3.2 Dialog 的 Window 創建過程

  1. 類似,但是 Context 必須是 Activity

8.3.3 Toast 的 Window 創建過程

  1. 具有定時取消,系統採用 Handler,有兩類 IPC(NotificationManagerService、NotificationManagerService回調 Toast 的 TN (Binder類)接口)
  2. mToast 最多同時存在 50 個 ToastRecord
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章