Android O Launcher3-Workspace載入
一.簡述:
Launcher這裡我們研究主要是Launcher3(Android O平臺),各個手機公司自家的ROM Launcher,咱們也看不到,但是八九不離十啦,他們也應該是重寫關鍵函式來實現他們的需要。
二.流程詳述:
1.核心方法:
LauncherProvider#loadDefaultFavoritesIfNecessary()
A.第一種:從某個設定好的APK(特定packageName)裡面取得xml
這裡關鍵實現方法為:createWorkspaceLoaderFromAppRestriction()。在這會去從UserManager獲取對應的Bundle物件,當Bundle物件中包含“workspace.configuration.package.name”的時候,回去獲取對應的apk的resouces。
接著繼續呼叫get()函式:1.首先獲取是否含有如,default_layout_6x6_h5.xml(有grid size和hotseat count拼接);2.然後獲取是否有如,default_layout_6x6.xml(有grid size拼接);3.最後獲取預設的default_layout.xml
B.第二種:從配置APK(與android.autoinstalls.config.action.PLAY_AUTO_INSTALL)讀xml
這裡呼叫AutoInstallsLayout中的get函式,最關鍵的實現函式是findSystemApk。根據特定的action:android.autoinstalls.config.action.PLAY_AUTO_INSTALL,來獲取是否system中有這發出的這個action的app,若有則去獲取apk的packagename和resource。
接著繼續呼叫get()函式:1.首先獲取是否含有如,default_layout_6x6_h5.xml(有grid size和hotseat count拼接);2.然後獲取是否有如,default_layout_6x6.xml(有grid size拼接);3.最後獲取預設的default_layout.xml
大致流程圖如下:
C.第三種:從一個preload特定名稱(com.android.launcher3.action.PARTNER_CUSTOMIZATION)的APK裡面取得xml
最關鍵的實現函式是findSystemApk。根據特定的action:android.autoinstalls.config.action.PLAY_AUTO_INSTALL,來獲取是否system中有這發出的這個action的app,若有則去獲取apk的packagename和resource。
接著通過hasDefaultLayout()來判斷apk中是否有partner_default_layout.xml,若有,則將此xml作為defaultlayout
這種情況可以參看google GMS中的一個GmsSampleIntegration 應用。
a.看他的AndroidManifest.xml:
<receiver android:name=".LauncherCustomizationReceiver">
<intent-filter>
<action android:name="com.android.launcher3.action.PARTNER_CUSTOMIZATION" />
</intent-filter>
</receiver>
b.資源目錄中有partner_default_layout.xml,其中有對佈局的定義。
D.第四種:從原生Launcher中讀取xml檔案(這裡根據桌面dimen去選取4*4 5*5 的xml檔案)
這裡主要是從InvariantDeviceProfile類中獲取到對應defaultLayoutId,然後通過DefaultLayoutParser類調到用其父類AutoInstallsLayout的建構函式中進行對xml檔案的解析。
獲取預設的defaultLayouId主要是在InvariantDeviceProfile中獲取的:在其建構函式中呼叫到getPredefinedDeviceProfiles(),會從device_profiles.xml中選擇合適的,選擇的方法是獲取螢幕的width和height來匹配xml檔案中的minWidthDps和minHeightDps,挑選開平方後值最相近的一個profiles。最終取到對應的defaultLayouId(對應default_workspace_3x3 、default_workspace_4x4等)
InvariantDeviceProfile的各個引數依次代表:
配置名字(任意定義)、最小寬度(單位是dp)、最小高度(單位是dp)、桌面行數、桌面列數、資料夾行數、資料夾列數、主選單中predicted apps最小列數、桌面Icon的size(單位是dp)、桌面Icon的文字size(單位是dp)、Hotseat的Icon個數、Hotseat的Icon的size(單位是dp)、預設的桌面配置LayoutId、demo apk的layuoutId。
大致的流程圖如下:
ps:xml檔案中元素的x 、y的值最終在layout中的位置:若為正,則即為x/y;若為負,則為行/列數-y/x
首次載入的時候會走上面四種中的某一種,最終這些會被載入到db檔案中,之後重啟等操作載入的就是直接從db中獲取出來的。
三.總結
1.如果有需求需要客製化的workspace,可以考慮在第四步中加入客製化的workspace.xml的載入實現即可;
2.Launcher 幾x幾的實現即在profiles中獲取的numRows和numColumns值來獲取;
3.後續會專開一篇大致講下xml的寫法。
FAQ(後續補充):