一.簡述:?
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:
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(后續補充):