編輯:關於Android編程
最近在項目中遇到了這樣的需求:需要在特定的其他應用之上懸浮自己的UI交互(拖動、輸入等復雜的UI交互),和九游的浮窗類似,不過我們的比九游的體驗更好,我們越過了很多授權的限制。
很多人都知道如何去實現一個簡單的浮窗,但是卻很少有人去深入的研究背後的流程機制,由於項目中浮窗交互比較復雜,遇到了些坑查看了很多資料,故總結浮窗涉及到的知識點:
* 窗口層級關系(浮窗是如何“浮”的)?
* 浮窗有哪些限制,如何越過用戶授權實現浮窗功能?
* 窗口與用戶輸入系統(Activity是如何接收到touch事件的)?
本章我們來研究第一個問題:浮窗為何會浮。浮窗之所以叫浮窗,是因為它能懸浮於應用或者桌面窗口之上,能脫離Activity而存在。為了研究其中區別,我們先來看看我們最熟悉的Activity是怎麼顯示出來的。
Activity是怎麼顯示出來的?
要弄清這個問題答案,我們先從Activity的setContentView()這個方法的源碼開始找起,在Activity中看到setCententView的源碼:
public void setContentView(int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
getWindow是返回返回Activity的mWindow變量,指向一個Window的對象,Window是一個抽象類,這裡返回的是PhoneWindow對象(PhoneWindow是Window的子類),PhoneWindow中有一個DecorView對象,decorView成員,這是一個FrameLayout,setContentView的子布局最終會添加到decorView中,這個decorView就是當前窗口的根視圖,這個根視圖是如何最終被繪制出來的?在ActivityThread中有這樣一段代碼:
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (a.mVisibleFromClient) {
a.mWindowAdded = true;
wm.addView(decor, l);
}
這個decorView,最終會被WindowManager.addView添加到繪制系統中,並類型是WindowManager.LayoutParams.TYPE_BASE_APPLICATION,這個參數決定了要繪制的窗口的z軸層次,為了避免思維棧過深,這裡就不貼出詳細的源碼跟蹤過程了,直接給結論。
先來看看Activity和window的關系:
再來window和View的關系:
Activity窗口顯示過程:
說Activity是怎麼顯示出來的,其實是說Activity管理的View是怎麼顯示出來的。最後再來總結一下:
一、Activity通過setContentView設置的視圖是添加到PhoneWindow的根視圖decor中。
二、Window是一個抽象的概念,Window關了了一個View(根視圖),最終被WindowManager管理的還是一個View(根視圖)和它的LayoutParams,視圖繪制刷新都是通過WindowManager(WindowManagerGlobal)與WindowManagerServiceIPC交互調用底層繪制的。
三、Activity是四大組件中唯一和窗體緊密聯系的組件(這是為什麼會有初學者把Activity直接理解為繪制界面的原因),所有掌管的視圖只不過是一種window和Dialog、Toast、牆紙所掌管的Window類型不一樣。
浮窗為什麼會“浮”?
上面講到Activity的顯示過程其實已經揭示了通用界面的顯示過程,浮窗的顯示過程更為簡單:
做過浮窗的同學應該都明白了,為啥浮窗能脫離Activity而顯示,本質上我們是把一個View交給WindowManager來管理了,LayoutParams.type類型決定了這個View顯示窗口的類型,不同類型顯示的窗口層次(z軸)是不一樣的。大方面來講可以分為應用窗口(APPLICATION_WINDOW)、子窗口(SUB_WINDOW)、系統窗口(SYSTEM_WINDOW)三種類型,應用窗口z軸范圍是1~99,子窗口的范圍是1001~1999,系統窗口是(2000~2999),所以要實現浮動窗口我們只能在系統窗口范圍中實現。
到這裡我們對Android系統的窗口層次有個大致的了解了,Activity是Android應用的四大組件之一,描述的是應用的活動狀態和周期,受ActivityManagerService的管理;Window/View是圖形窗口的抽象模型,描述的是窗口的繪制信息,受WindowManagerService的管理;Activity聚合Window來和圖形窗口產生聯系。文章旨在理解一下Android窗體系統的一個雛形,能力有限不能詳細跟蹤整個窗口體系的源碼,有興趣的可以自己深入.
FFBM: fast factory boot mode,快速工程啟動模式此函數主要是如何解析boot.img和recovery.img的頭部信息,提取這兩部分的參數,傳
一、問題描述 Android應用中經常涉及從網絡中加載大量圖片,為提升加載速度和效率,減少網絡流量都會采用二級緩存和異步加載機制,所謂二級緩存就是通過先從內存中獲
在Android開發中,經常需要加載顯示網頁,一般一個頁面在打開後,在等待數據加載的過程中,都需要花一點時間,這個時候往往需要顯示一個轉動的進度條(ProgressBar
本文實例講述了Android開發之ListView列表刷新和加載更多實現方法。分享給大家供大家參考。具體如下:上下拉實現刷新和加載更多的ListView,如下:packa