編輯:Android開發教程
窗口管理是android的一個核心內容。它管理著窗口的創建和銷毀,布局和大小,焦點的控制等等。
窗口可以分為兩類:
一種是應用窗口,即由具體應用創建的窗口,其實其中還可以細分出父窗口和子窗口。窗口一般都會對應一個activity。
一種是系統窗口,如狀態欄,這類窗口由系統直接通過windowManager來創建,和activity無關。
在這裡,窗口的概念其實可以說由三部分構成,一部分是用來描述窗口信息的,由WindowState對象表示。一個WindowState對象對應一個窗口,它擁有繪制窗口所需要的信息。但是真正去繪制窗口需要另一部分內容Surface來完成,最終會通過surfaceflinger完成繪圖。還有一部分就是對消息的處理,windowmanagerService把窗口信息傳遞給InputManager,這樣InputDispatcher就能根據當前窗口的狀態進行消息處理。
我們先看下整體的架構圖,然後再來看這兩種窗口的創建。WindowManager和其他很多android的服務一樣,采用C/S的架構。其中windowManagerService跑在System_server進程,作為服務端,客戶端通過ipc調用和它進行交互。
我們通過完整的應用程序窗口創建流程來了解這個結構和整個過程。我們不去糾結其中代碼的一些細枝末節的東西,通過整體和重要的東西來看。
一.客戶端部分
在客戶端,在應用啟動的時候,ActivityThread會調用performLaunchActivity方法,去實例化一個activity,同時調用attach方法,並傳遞很多和activity相關的參數信息。其中有個比較重要的東西是一個IBinder對象token,這個token成為activity的標識,windowmanagerService可以通過這個token獲得activity當前的運行狀態。在WindowManager中會通過該token生成一個WindowToken對象,一個父窗口對應一個WindowToken,而具有相同token的所有其子窗口都會被歸到一個WindowToken中。即如果token相同,表示他們都會在一個窗口中。還有個用來標識窗口的類AppWindowToken,繼承自WindowToken,它由activity傳過來的token生成,和Activity一一對應。通過token,就能找到activity和window的對應關系了。
繼續往下看,attach方法會通過代碼mWindow = PolicyManager.makeNewWindow(this)實例化一個phoneWindow對象,但是這個對象還是比較抽象的東西。在activity開始oncreate調用時,會調用setContentView方法。會去獲得之前那個phoneWIndow對象對應的DecorView,最後通過層層窗口修飾(狀態欄等)後調用activity的makeVisible方法,在方法中通過addiew方法完成窗口的添加。
windowManager只是提供接口,用了橋接模式,真正實現是WindowManagerImpl類。而調用addiew方法的對象來自另一個類LocalWindowManager,它會做一些簡單檢查,再通過WindowManagerImp類的addview完成窗口添加。addview大概分三步執行:
1.校驗該窗口是否已經添加過了。
2.判斷窗口類型如果是子窗口,則找到它附屬的父窗口
3.new一個ViewRootImpl對象,最後調用該對象的setView方法。
setView 方法會最終會通過ipc調用IwindowSession的add方法。Session類實現了該方法,並最終給WindowManagerService處理。客戶端的工作至此就完成了。
這裡說明一下ViewRootImpl類,這其實是個handler。自然的,它一部分功能就是對消息進行處理,將用戶的一些操作分發到view中。它也是view和WindowManagerService的橋梁。可以看到它通過一個會話將信息傳遞到了WindowManagerService。而WIndowManagerService也會通過IWindow接口將指令通過消息的方式發送到ViewRootImpl,ViewRootImpl處理這些消息。
查看本欄目更多精彩內容:http://www.bianceng.cn/OS/extra/
谷歌發布了最新的Android 4.4 KitKat 奇巧巧克力操作系統,不過,該系統的組要打擊對象,並非微軟的Windows Phone 操作系統,而是微軟的 Offi
其實我一直准備寫一篇關於Android事件分發機制的文章,從我的第一篇博客開始,就零零散散在好多地 方使用到了Android事件分發的知識。也有好多朋友問過我各種問題,比
Android下面使用命令行截圖。因為工作調試用的機器,沒法連接USB,所以用不了一般的截圖方法,後來查了一下,Android4.0以後都內置了截圖命令。可以使用下面命令
Remote Service Controller 和使用Local Service的Android ApiDemo示例解析(40):App->Service-&g