一.简述:
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(后续补充):