android Q launcher 数据加载流程

时间:2020/08/24
之前公司不允许csdn,笔记写在其它地方。最近整理过来
下一篇:launcher数据加载(二)

前言

androidQ和androidP上Launcher结构有很大区别。

LoaderTask从LauncherModel中分离出来
LoaderTask也没有直接取调用LauncherProvider,而是通过LauncherSetting.call
LauncherSetting:工具类,保存Launcher中用到的一些静态值,类似于key值。

加载流程

LoaderTask->run()

1、loadworkspace

//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直接调用该方法,区别不是很大)
2、loadDefaultFavoritesIfNecessary
//loadDefaultFavoritesIfNecessary里根据条件,从不同的路径加载默认布局文件
//执行条件
getFlagEmptyDbCreated
1AutoInstallsLayout 
launcher3.layout.provider    根据key获取系统provider
2AutoInstallsLayout
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
2.1、加载默认配置的条件
//执行条件的标志位初始化
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
2.2、默认配置路径说明
ED6109G项目默认配置:
2AutoInstallsLayout
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方法中,查询数据库–>加载数据库里的布局/加载默认布局(首次启动数据库只有默认布局的数据,所以效果看上去只加载了默认布局)

3、图标加载

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
4、数据库信息解读

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信息
5、allapps列表界面排序
mResults.bindAllApps();-->launcher.bindAllApplications-->AllAppsStore.setApps-->AllAppsStore.addOrUpdateApps-->AllAppsStore.notifyUpdate-->AlphabeticalAppsList.onAppsUpdated
onAppsUpdated这里面处理排序
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值