时间:2020/08/24
之前公司不允许csdn,笔记写在其它地方。最近整理过来
下一篇:launcher数据加载(二)
androidQ和androidP上Launcher结构有很大区别。
LoaderTask从LauncherModel中分离出来
LoaderTask也没有直接取调用LauncherProvider,而是通过LauncherSetting.call
LauncherSetting:工具类,保存Launcher中用到的一些静态值,类似于key值。
LoaderTask->run()
//loading default favorites
通过call方法调用到LauncherProvider对应的方法(和之前的流程一样,调用方式稍微有点区别)
Log.d(TAG, "loadWorkspace: loading default favorites");
LauncherSettings.Settings.call(contentResolver,
LauncherSettings.Settings.METHOD_LOAD_DEFAULT_FAVORITES);
//LauncherProvider中重写call方法,根据传入的string调用到loadDefaultFavoritesIfNecessary(P上是launchermodel直接调用该方法,区别不是很大)
//loadDefaultFavoritesIfNecessary里根据条件,从不同的路径加载默认布局文件
//执行条件
getFlagEmptyDbCreated
1、AutoInstallsLayout
launcher3.layout.provider 根据key获取系统provider
2、AutoInstallsLayout
android.autoinstalls.config.action.PLAY_AUTO_INSTALL
//Google PAI的在线布局就是这里获取的布局资源文件。
3、partner_default_layout
com.android.launcher3.action.PARTNER_CUSTOMIZATION 根据action获取应用资源,加载资源
//默认是指向gms包里的vendor/partner_gms/apps/GmsSampleIntegration
4、device_profiles.xml中读取配置,defaultLayoutId的值,例如default_workspace_3x3 apk本地资源
//创建数据库
mOpenHelper.createEmptyDB
//解析加载布局文件,默认配置插入数据库
mOpenHelper.loadFavorites-->parseLayout-->parseAndAddNode-->addShortcut-->insertAndCheck-->dbInsertAndCheck(launcher.db favorites table )
//最后
clearFlagEmptyDbCreated
//执行条件的标志位初始化
LoaderTask.loadWorkspace-->GridSizeMigrationTask.migrateGridIfNeeded-->Settings.call(
context.getContentResolver(), Settings.METHOD_NEW_TRANSACTION)-->LauncherProvider.createDbIfNotExists-->DatabaseHelper.<init>-->getReadableDatabase()
//getReadableDatabase时,底层调用到DatabaseHelper.onCreate
DatabaseHelper.onCreate-->DatabaseHelper.onEmptyDbCreated-->LauncherProvider.setFlagEmptyDbCreated
ED6109G项目默认配置:
2、AutoInstallsLayout
android.autoinstalls.config.action.PLAY_AUTO_INSTALL
//Google PAI的在线布局就是这里获取的布局资源文件。
需要内置PlayAutoInstallStub底包,刷机oobe界面联网登录Google账号,会根据Android Device Config Portal (ADCP)后台配置下载完整的包PlayAutoInstallConfig,并自动下载配置的应用,使用布局文件。
ADCP账号一般掌握在甲方爸爸手里,我们提供完整的apk包和配置说明,让甲方爸爸帮忙配置。
3、partner_default_layout.xml
按照代码定位到配置在:com.google.android.gmsintegration(代码打印包名)
apk位置:/product/app/GmsSampleIntegration/GmsSampleIntegration.apk
代码位置:vendor\partner_gms\apps\GmsSampleIntegration\res_dhs_full\xml
修改默认配置后,需要重新生成GmsSampleIntegration.apk安装验证默认布局
之后回到loadworkspace方法中,查询数据库–>加载数据库里的布局/加载默认布局(首次启动数据库只有默认布局的数据,所以效果看上去只加载了默认布局)
step 1.1: loading workspace
//loadworkspace中,上面读取到数据库内容后,对内容进行解析,并获取app info,如title 和icon
else if (c.itemType ==
LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {//item类型
info = c.getAppShortcutInfo(//构造iteminfo的入口
intent, allowMissingTarget, useLowResIcon);
//默认配置,获取图标的调用堆栈
at com.android.launcher3.IconProvider.getIcon(IconProvider.java:27)
at com.sprd.ext.dynamicicon.DynamicIconProvider.getIcon(DynamicIconProvider.java:36)
at com.android.launcher3.icons.IconCache.getFullResIcon(IconCache.java:246)
at com.android.launcher3.icons.IconCache.getFullResIcon(IconCache.java:242)
at com.android.launcher3.icons.LauncherActivtiyCachingLogic.loadIcon(LauncherActivtiyCachingLogic.java:52)
at com.android.launcher3.icons.LauncherActivtiyCachingLogic.loadIcon(LauncherActivtiyCachingLogic.java:25)
at com.android.launcher3.icons.cache.BaseIconCache.cacheLocked(BaseIconCache.java:340)
at com.android.launcher3.icons.cache.BaseIconCache.cacheLocked(BaseIconCache.java:312)
at com.android.launcher3.icons.IconCache.getTitleAndIcon(IconCache.java:211)
at com.android.launcher3.icons.IconCache.getTitleAndIcon(IconCache.java:175)
at com.android.launcher3.model.LoaderCursor.getAppShortcutInfo(LoaderCursor.java:275)
at com.android.launcher3.model.LoaderTask.loadWorkspace(LoaderTask.java:478)
at com.android.launcher3.model.LoaderTask.run(LoaderTask.java:179)
//info是LauncherActivityInfo,调用这个接口获取图标
info.getIcon(iconDpi)//这里获取到的就是已经变形的图了
//launcher中另外一种获取图标的方式,上面的方式其实底层也是调用的这个方式
resources.getDrawableForDensity(id, mFillResIconDpi),
step 2.1: loading all apps
//loadallapps
//查询手机安装的所有应用
// Query for the set of apps
final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
//最终调用到底层,查询main launcher的activitys
com/android/server/pm/LauncherAppsService.java
ParceledListSlice<ResolveInfo> launcherActivities = queryActivitiesForUser(
callingPackage,
new Intent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_LAUNCHER)
.setPackage(packageName),
user);
com/android/server/pm/PackageManagerService.java
queryIntentActivitiesInternal();
//图标获取和上面加载默认配置图标差不多,只是触发的地方不同而已
at com.android.launcher3.IconProvider.getIcon(IconProvider.java:27)
at com.sprd.ext.dynamicicon.DynamicIconProvider.getIcon(DynamicIconProvider.java:36)
at com.android.launcher3.icons.IconCache.getFullResIcon(IconCache.java:246)
at com.android.launcher3.icons.IconCache.getFullResIcon(IconCache.java:242)
at com.android.launcher3.icons.LauncherActivtiyCachingLogic.loadIcon(LauncherActivtiyCachingLogic.java:52)
at com.android.launcher3.icons.LauncherActivtiyCachingLogic.loadIcon(LauncherActivtiyCachingLogic.java:25)
at com.android.launcher3.icons.cache.BaseIconCache.cacheLocked(BaseIconCache.java:340)
at com.android.launcher3.icons.cache.BaseIconCache.cacheLocked(BaseIconCache.java:312)
at com.android.launcher3.icons.IconCache.getTitleAndIcon(IconCache.java:211)
at com.android.launcher3.icons.IconCache.getTitleAndIcon(IconCache.java:175)
at com.android.launcher3.AllAppsList.add(AllAppsList.java:83)
at com.android.launcher3.model.LoaderTask.loadAllApps(LoaderTask.java:834)
at com.android.launcher3.model.LoaderTask.run(LoaderTask.java:196)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.os.HandlerThread.run(HandlerThread.java:67)
step 3.1: loading deep shortcuts
ShortcutManager.queryForAllShortcuts(user);
//根据不同的mk导入不同的DeepShortcutManager.java
public List<ShortcutInfo> queryForAllShortcuts(UserHandle user) {
return query(FLAG_GET_ALL, null, null, null, user);
}
//调用到getShortcuts
LauncherApps.getShortcuts(q, user);
↓
mService.getShortcuts(mContext.getPackageName(),
query.mChangedSince, query.mPackage, query.mShortcutIds, query.mActivity,
query.mQueryFlags, user)
...
//具体查询方式后面跟一下
...
step 4.1: loading widgets
List<ComponentWithLabel> allWidgetsList = mBgDataModel.widgetsModel.update(mApp, null);//这里会调用到插入数据库,见下方 插入时机2
//根据不同的mk走到不同的WidgetsModel.java
//具体的数据加载方法
// Widgets
AppWidgetManagerCompat widgetManager = AppWidgetManagerCompat.getInstance(context);
for (AppWidgetProviderInfo widgetInfo : widgetManager.getAllProviders(packageUser)) {
LauncherAppWidgetProviderInfo launcherWidgetInfo =
LauncherAppWidgetProviderInfo.fromProviderInfo(context, widgetInfo);
widgetsAndShortcuts.add(new WidgetItem(
launcherWidgetInfo, idp, app.getIconCache()));
updatedItems.add(launcherWidgetInfo);
}
// Shortcuts
for (ShortcutConfigActivityInfo info : LauncherAppsCompat.getInstance(context)
.getCustomShortcutActivityList(packageUser)) {
widgetsAndShortcuts.add(new WidgetItem(info, app.getIconCache(), pm));
updatedItems.add(info);
}
setWidgetsAndShortcuts(widgetsAndShortcuts, app, packageUser);
//插入数据库的时机
插入时机2、
//插入数据包类名都是包名,表示拥有widgets的应用的数据,数据如下:
rowid componentName profileId lastUpdated version icon icon_color label system_state
12 com.google.android.calendar/com.google.android.calendar. 0 1599004063000 2016416004 [BLOB_DATA] -13475377 日历 zh-Hans-CN,en-US,29
at com.android.launcher3.icons.cache.BaseIconCache.addIconToDB(BaseIconCache.java:286)
at com.android.launcher3.icons.cache.BaseIconCache.getEntryForPackageLocked(BaseIconCache.java:450)
at com.android.launcher3.icons.IconCache.getTitleAndIconForApp(IconCache.java:219)
at com.android.launcher3.model.WidgetsModel.setWidgetsAndShortcuts(WidgetsModel.java:216)
at com.android.launcher3.model.WidgetsModel.update(WidgetsModel.java:111)
at com.android.launcher3.model.LoaderTask.run(LoaderTask.java:227)
step 4.3: Update icon cache
插入时机1、3、
//插入时机1、
//插入时机3、
at com.android.launcher3.icons.cache.BaseIconCache.addIconToDB(BaseIconCache.java:286)
at com.android.launcher3.icons.cache.BaseIconCache.addIconToDBAndMemCache(BaseIconCache.java:273)
at com.android.launcher3.icons.cache.IconCacheUpdateHandler$SerializedIconUpdateTask.run(IconCacheUpdateHandler.java:283)
IconCacheUpdateHandler.updateIconsPerUser
IconCacheUpdateHandler.updateIcons
//触发点LoaderTask.run中updateIcons
updateHandler.updateIcons(allActivityList,
new LauncherActivtiyCachingLogic(mApp.getIconCache()),
mApp.getModel()::onPackageIconsUpdated);//插入所有安装应用的数据
updateHandler.updateIcons(allWidgetsList, new ComponentCachingLogic(mApp.getContext()),
mApp.getModel()::onWidgetLabelsUpdated);//插入数据的是widgets
launcher.db插入的是workspace和host上的数据(图标、文件夹、widget )
app_icons.db插入的是应用安装信息和widgets列表信息
widgetpreviews.db插入的widgets列表里的widgets信息,包含预览图
app_icons.db中
//deepshortcut没有数据插入数据库
//为啥时机2的数据在数据库前面呢?
//因为是直接操作数据库进行插入,而时机1、3调用updateHandler.updateIcons,其核心是起一个Task,mIconCache.mWorkerHandler.postAtTime
//和LoaderTask共用一个looper,加载流程走完,才会真正的run起来
//插入时,采用pop的方式一次写入一个数据,如果还有数据则把自己post到队列。
//所以数据库的数据格式,应用、widget、应用、widget...依次循环,直到某一方完全没有数据,另一方一直写到数据结束
//最终数据库的数据从上往下
//支持widget的app
//安装APP信息
//widget信息
//安装APP信息
//widget信息
mResults.bindAllApps();-->launcher.bindAllApplications-->AllAppsStore.setApps-->AllAppsStore.addOrUpdateApps-->AllAppsStore.notifyUpdate-->AlphabeticalAppsList.onAppsUpdated
onAppsUpdated这里面处理排序