當前位置:編程學習大全網 - 源碼下載 - SystemUI深淺色主題隨壁紙改變的流程探析

SystemUI深淺色主題隨壁紙改變的流程探析

在Android8.1上有壹個新增的特性,當妳修改了自己的壁紙時(壁紙的主色調必須有差別,比如從白色壁紙更改為黑色壁紙),妳的Android設備的下拉QS、音量調節框、關機對話框等的背景色都會隨之改變。

並且在9.0系統上,Google還為這個功能添加了壹項開關,用戶可以強制設置主題背景色:

廢話不多說,從源碼裏來看看根據壁紙的這整套流程是怎麽實現的。

首先簡單介紹下Android如何修改系統壁紙,如果是第三方應用首先要申請系統權限:

然後需要通過WallpaperManager相關的接口進行靜態壁紙的設置。

WallpaperManager提供了setBitmap(bitmap)、setResource(resid)、setStream(inputstream)這三個方法來設置靜態壁紙,下面以setBitmap的源碼為例來說明壹下。

從以上方法來看,設置壁紙的過程有進行寫文件操作,我們知道SystemUI的靜態壁紙是ImageWallpaper,那麽上述過程是如何通知到ImageWallpaper的呢。下面就來介紹WallpaperManagerService裏的壹個重要組件:WallpaperObserver。

WallpaperObserver繼承自FileObserver,而FileObserver類是壹個用於監聽文件訪問、創建、修改、刪除、移動等操作的監聽器,可以監聽壹個文件或者壹個文件夾,並在上述動作發生時回調onEvent()方法。

回到上面講的setBitmap方法,會通過WallpaperManagerService的setWallpaper()方法獲得壹個文件描述符,

再看updateWallpaperBitmapLocked()的實現:

從以上實現可知,文件路徑是用getWallpaperDir()方法獲得的,了解了這點,就方便介紹WallpaperObserver了。在它的構造方法裏,會將getWallpaperDir()取得的路徑傳回給父類的構造方法,從而開始監聽wallpaper的CLOSE_WRITE事件。

下面是用於回調的onEvent()方法的實現:

notifyColorsWhich 是壹個int值,初始時為0,當通過Wallpaper path取到的新壁紙File與之前保存的全局變量不壹致時,即有壁紙更新,notifyColorsWhich 會與FLAG_SYSTEM進行按位或運算;

notifyWallpaperColorsChanged()方法又會將參數傳給notifyColorListeners()方法去處理,這裏就直接跳到notifyColorListeners()的實現:

notifyWallpaperColorsChanged()方法會分別通知系統壁紙和鎖屏壁紙顏色改變的監聽者,我們暫時只先分析系統壁紙相關的流程。在這個方法裏,首先會通過mColorsChangedListeners取得當前userId的壹個RemoteCallbackList,這個類是壹個系統層的容器類,容納的對象是壹些接口mCallbacks ,用於執行列表中對象的回調函數,裏面有幾個比較重要的方法:

看的出WallPaperObserver的currentUserColorListeners裏存放的是壹些IWallpaperManagerCallback對象,之後通過getBroadcastItem()遍歷出所有的callbacks,並分別調用每個callback的onWallpaperColorsChanged()。

StatusBar的onStart()方法中有這麽壹步:

SysuiColorExtractor繼承於ColorExtractor,後者又實現了WallpaperManager.OnColorsChangedListener

在SysuiColorExtractor的構造函數裏,通過WallpaperManager的addOnColorsChangedListener()方法,把自身這個OnColorsChangedListener給註冊過去,最終會調用到WallpaperManager.sGlobals的addOnColorsChangedListener():

然後會把自己這個IWallpaperManagerCallback以及userId,通過WallpaperManagerService的registerWallpaperColorsCallback()方法傳遞過去:

到這壹步就和上壹節的通知過程對應上了,給mColorsChangedListeners添加新的RemoteCallbackList對象,並註冊相應的callback進去(這裏的callback是壹個Globals對象),方便後續通知。

好了,註冊過程講完了,最後再來看看SystemUI是怎麽響應壁紙顏色改變的。回到上壹節的最末尾,我們說到 “通過getBroadcastItem()遍歷出所有的callbacks,並分別調用每個callback的onWallpaperColorsChanged()”,已經知道這壹處的callback是WallpaperManager裏的Globals類的對象了,找到它的實現:

在前面的註釋中已經介紹過,存在listener這個Pair裏的first是壹個ColorExtractor,回到SystemUI,

遍歷mOnColorsChangedListeners裏的所有listener並調用其onColorsChanged()方法,在這壹節的最開始我們有提到StatusBar把自己作為參數通過addOnColorsChangedListener()傳給了ColorExtractor,之後便被加入到mOnColorsChangedListeners裏面,過程很簡單,這裏就不再贅述了。之後自然是調用StatusBar的onColorsChanged()了:

最後在updateTheme()這個方法中修改SystemUI相關的深色和淺色主題。

以上就是整個註冊以及響應的流程了,至於到了updateTheme()之後SystemUI是以怎樣的方式去具體修改那些控件的主題的,後續有時間會繼續再研究壹下。

  • 上一篇:圖書小程序源代碼
  • 下一篇:誰能幫我推薦壹款性能高的服務器,最好帶配置參數
  • copyright 2024編程學習大全網