Launcher8.0启动流程的第六步中loadworkspace的第2小步的做好准备后,已经锁定对于的数据库,并且开启循环读取模式,接着就是依次将读取的内容放入缓存中。
直接上源码,由于源码太长,无法分隔成多个小步来简化记忆。
分析以注释的形式放在源码中间。
boolean allowMissingTarget = false;
switch (c.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
//对数据库每一条的读取方式,按照类型区分,最常见的是图标类型,SHORTCUT、APPLICATION、DEEP_SHORTCUT都是图标类型。图标类型,在桌面上占据1x1的格子,且点击打开对应应用的属于图标大类。
intent = c.parseIntent();
if (intent == null) {
c.markDeleted("Invalid or null intent");
continue;
}
以上代码有从c获取intent,其源码如下:
public Intent parseIntent() {
String intentDescription = getString(intentIndex);
try {
return TextUtils.isEmpty(intentDescription) ?
null : Intent.parseUri(intentDescription, 0);
} catch (URISyntaxException e) {
Log.e(TAG, "Error parsing Intent");
return null;
}
}
intentIndex是之前构造器里面的数据库的对应参数。
intentIndex = getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
在intent参数来源有三处。一个是xml文件中,在首次开机的时候。一个是packagemanager,手机里面按照的应用的intent都是知道的。最后是快捷方式生成的intent。 Intent是用来启动应用的参数。
回到loadworksapce源码:
int disabledState = quietMode.get(c.serialNumber) ?
ShortcutInfo.FLAG_DISABLED_QUIET_USER : 0;
ComponentName cn = intent.getComponent();
targetPkg = cn == null ? intent.getPackage() : cn.getPackageName();
//对c.user进行判断,shortcut只在默认用户显示。
if (!Process.myUserHandle().equals(c.user)) {
if (c.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
c.markDeleted("Legacy shortcuts are only allowed for default user");
continue;
} else if (c.restoreFlag != 0) {
// Don't restore items for other profiles.
c.markDeleted("Restore from managed profile not supported");
continue;
}
}
//检查是否有对应的package name,如果没有传入包名则不是应用
if (TextUtils.isEmpty(targetPkg) &&
c.itemType != LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
c.markDeleted("Only legacy shortcuts can have null package");
continue;
}
boolean validTarget = TextUtils.isEmpty(targetPkg) ||
launcherApps.isPackageEnabledForProfile(targetPkg, c.user);
//检查对应的应用是否在系统中为disable状态,如果为disable状态,则不显示。通过isActivityEnabledForProfile来判断。 当用户在设置里面对某个应用设置为disable,回到Launcher的时候,Launcher的数据库里面还是保留着该应用。这里会进行一个判断,当数据库有,但手机不支持的时候,不显示。
if (cn != null && validTarget) {
if (launcherApps.isActivityEnabledForProfile(cn, c.user)) {
c.markRestored();
} else {
//有一种特例,应用还没有安装到手机,也就是手机不支持,但是该应用处于下载状态。而且是在autointall的布局中,首先定义了其位置。这种时候,则可以显示。
if (c.hasRestoreFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
intent = pmHelper.getAppLaunchIntent(targetPkg, c.user);
if (intent != null) {
c.restoreFlag = 0;
c.updater().put(
LauncherSetting