资讯动态

Android 10 屏蔽 Launcher HOME 属性报错修复:原理与工程实践

发布时间:2026/10/21 8:24:46 来源:尧图企业网站定制
前阵子帮某方案商调一批 Android 10 的行业定制机需求听起来不复杂设备开机之后只能停留在自研的那套点餐/广告界面用户怎么按都回不到原生 Launcher。开发同学上手很快直接把原生 Launcher 的 HOME 属性屏蔽了。结果屏蔽完不到十分钟系统里到处都在报ActivityNotFoundExceptionSettings 崩、SystemUI 黑屏、按 HOME 键没反应连开机动画都能卡住。这篇文章就把从“屏蔽原生 Launcher 的 HOME 属性”到“修复由此引发的一串调用报错”的完整过程写下来包括原理、改法、修法和验证给同样在搞行业定制、电视盒子、车载中控或广告机的朋友一个参考。1. 定制设备为什么非要跟 HOME 属性较劲1.1 封闭场景下“不让人回到原生桌面”意味着什么餐厅点餐机、酒店自助机、医疗器械、车载后装屏这类设备产品经理的诉求往往是“整台机器看起来就是一个应用”。从用户体验上讲无论用户怎么点最终都要落在自研的全屏界面里系统桌面不应该出现也不应该允许用户通过某种方式跳回原生 Launcher。这种封闭诉求落到 Android 系统层第一个要解决的就是“谁是默认桌面”的问题。Android 系统本身并不知道你的自研界面是桌面它只知道一个规则找Intent.ACTION_MAIN Intent.CATEGORY_HOME的 Activity。只要原生 Launcher 还声明着这个组合它就有资格在开机启动、按 HOME 键、语音助手调用等场景里被系统拉起来。也就是说只要 HOME 属性还在原生 Launcher 就永远是“合法桌面候选”哪怕你把它从桌面上隐藏了系统机制还是会找到它。所以很多方案商的开发同学上来就想把原生 Launcher 的 HOME 属性摘掉让系统彻底不认为它还能当桌面。这个思路本身没错但摘掉之后引发的连锁反应往往被严重低估了。1.2 直接禁用 Launcher 包为什么会“伤敌一千自损八百”第一反应通常是“直接把原生 Launcher 包 disable 掉不就行了”实际项目里我基本不建议这么干原因有几个系统开机时依赖一个“客户端侧 Home”来结束启动流程。如果没有可用的 HOME 候选开机动画会卡住反复起不来。原生 Launcher 不只是桌面还承担着壁纸绑定、Shortcut 管理、QuickStep 代理、无障碍焦点等一堆隐式功能。禁用整个包等于把这些服务也一起禁掉了。系统 UI 里很多逻辑都默认“设备里一定存在某个 Launcher”直接禁用包的后果是bindService失败、查询到空列表出现一堆跟 Launcher 名字有关的间接崩溃。从工程回滚的角度看禁用包是一次运行时状态修改如果你想验证是不是它引起的恢复倒是简单但如果要交付量产版本这种状态很容易被恢复出厂设置或者其他用户操作破坏。所以我更倾向于“让系统不再认为原生 Launcher 是 Home 候选”而不是把 Launcher 整个从设备里抹掉。1.3 屏蔽 HOME 属性和禁用组件到底有什么区别这里有一个很多新手容易混淆的概念屏蔽 HOME 属性和禁用 Launcher 组件虽然最终效果都是“原生 Launcher 不再被当作默认桌面”但作用位置完全不同。维度屏蔽 HOME 属性禁用 Launcher 组件/包修改位置AndroidManifest 里的 intent-filter 声明或 PMS 查询结果过滤PMS 维护的组件 enabled 状态原生 Launcher 本身包仍然可用服务仍能正常调用包内组件被 disable服务全部失效对壁纸/Shortcut/QuickStep 等系统依赖基本不受影响容易引发系统 UI 连锁崩溃恢复方式需要重新编译 system 镜像或关掉 PMS 过滤开关pm enable即可恢复典型适用场景整机 ROM 定制需要稳定交付调试阶段快速验证不建议量产用理解了这层区别后面看报错就顺了。屏蔽 HOME 属性本质上只是把一个组件从“桌面候选名单”里摘掉并没有把它杀死。系统其他服务如果还按旧逻辑去调用它不一定会崩真正崩的是那些“按照系统里一定存在 Home 候选”来写代码的模块。2. 屏蔽之后发生的连锁反应先看报错再谈原理2.1 最典型的 ActivityNotFoundException开机和按 HOME 键都找不到“家”我处理的那台项目 X 设备当时情况是系统里除了原生 Launcher还塞了一个自研 Launcher包名是com.example.kiosk开发同学把原生 Launcher 的 HOME 属性屏蔽掉之后以为一切正常。结果重启之后开机动画停留了很久然后屏幕黑了一阵logcat 里反复刷这样的日志08-12 10:23:01.123 1234 1234 E ActivityTaskManager: startHomeActivityLocked: No home activity found 08-12 10:23:01.124 1234 1234 E ActivityTaskManager: Failed to start home activity 08-12 10:23:02.001 8765 8765 E AndroidRuntime: FATAL EXCEPTION: main Process: com.android.settings, PID: 8765 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.settings/.SettingsActivity$DefaultHomeActivity} at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2450)第一行日志是系统在开枪时尝试启动 Home Activity结果resolveActivity返回为 null系统直接放弃。第二行之后跟着的就是连锁反应SystemUI、Settings 这些依赖“存在一个 Home”的模块开始各自崩溃。按 HOME 键的场景也一样。Android 的 PhoneWindowManager 接收到 HOME 键之后会通过ActivityTaskManager.startHomeActivity() 请求系统拉起桌面。如果当前没有 Home 候选就会抛出ActivityNotFoundException表现出来就是黑屏几秒、无响应、甚至直接回到锁屏。2.2 Settings 主屏幕应用入口异常看似不致命但定制版会崩这个报错很有代表性因为很多同学是在“默认应用”页面里点“主屏幕应用”时才发现的。屏蔽掉原生 Launcher 的 HOME 属性之后系统里只剩一个自研 Launcher 是 Home 候选按理说 Settings 应该直接显示自研 Launcher。但问题是原生 Launcher 之前已经被记录进Settings.Secure.HOME_CURRENT这类系统设置里了现在对应的组件又匹配不上于是 Settings 的DefaultHomePreferenceController在处理 ResolveInfo 时拿到 null直接 NPEjava.lang.NullPointerException: Attempt to invoke virtual method android.content.pm.ActivityInfo android.content.pm.ResolveInfo.activityInfo on a null object reference at com.android.settings.applications.defaultapps.DefaultHomePreferenceController.getDefaultHomeIntent这不算最难修的但它特别容易暴露“你在屏蔽属性的时候没有把所有依赖旧默认桌面的状态清理掉”这个问题。2.3 Recents 与 SystemUI 的间接故障不全是 HOME 属性的锅还有一类现象容易被误解比如最近任务界面消失、上滑手势没法回到桌面、SystemUI 莫名重启。这些不一定都是 HOME 属性缺失直接造成的但确实和 Launcher 的状态变化有关。Android 10 的 QuickStep 手势导航是通过Intent.ACTION_QUICKSTEP绑定到 Launcher 的代理服务来实现的。如果项目里自研 Launcher 没有实现对应的 QuickStep 契约而原生 Launcher 又被“摘掉”了 Home 资格SystemUI 在绑定OverviewProxyService时就会反复失败甚至导致 SystemUI 整个进程崩溃重启。这个链路比较隐蔽排查时不要只盯着“HOME 属性”这一点还要看QuickStep绑定日志。毕竟屏蔽 HOME 属性的目标是“让原生 Launcher 不当默认桌面”并不代表系统里其他依赖 Launcher 功能的服务都自动切换到自研实现。3. “家”到底是怎么被找到的HOME 属性与隐式 Intent 的解析链路3.1 Activity 里的 intent-filter 是怎么声明“我是桌面”的Android 判断一个应用是否桌面完全看 AndroidManifest 中某个 Activity 的 intent-filter 内容。原生 Launcher 的配置一般长这样activity android:namecom.android.launcher3.Launcher android:launchModesingleTask ... intent-filter action android:nameandroid.intent.action.MAIN / category android:nameandroid.intent.category.HOME / category android:nameandroid.intent.category.DEFAULT / /intent-filter /activity这里的三个元素各有作用action MAIN表示这是一个“入口 Activity”没有它系统不会把这个 Activity 当作顶级入口。category HOME表明这个 Activity 希望成为系统的“家”也就是桌面。这是最关键的标记。category DEFAULT为了保证能够被隐式 Intent 解析到而存在的。系统在查 Home 候选时通常带MATCH_DEFAULT_ONLY所以没有 DEFAULT 的话即使有 MAINHOME 也不一定解析得到。所以如果只想屏蔽某组件的 HOME 属性把category android:nameandroid.intent.category.HOME /这一行删掉即可。要是只留着 MAINHOME 但把 DEFAULT 删掉你可能会看到系统查询出来结果里没有它但那不是“屏蔽 HOME”的成功而是“DEFAULT 缺失导致无法匹配”容易被误判。3.2 开机时系统按什么顺序挑选桌面开机启动后ActivityTaskManagerService会构造一个隐式 IntentIntent homeIntent new Intent(Intent.ACTION_MAIN); homeIntent.addCategory(Intent.CATEGORY_HOME); homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);然后调用PackageManagerInternal.resolveHomeActivity()去查找当前用户下可用的 Home Activity。这个过程大致是系统会先看Settings.Secure.HOME_CURRENT里有没有记录用户/厂商预设的默认桌面组件。如果有并且该组件仍然能匹配ACTION_MAIN CATEGORY_HOME就直接用它。如果没有记录或者记录失效就查询所有匹配这个 Intent 的 Activity。如果查询结果只有一个直接启动如果有多个系统就会弹出一个“选择主屏幕应用”的对话框让用户选。屏蔽原生 Launcher 的 HOME 属性后如果自研 Launcher 还带 HOME 属性理论上系统应该直接解析到自研 Launcher。但如果你在屏蔽时把系统里最后一个 Home 候选也弄没了那resolveHomeActivity()就会返回 null开机流程直接卡在“找不到桌面”这一步。3.3 默认桌面弹窗和“主屏幕应用”设置的执行逻辑Android 10 里“默认桌面”这个状态本质上是一笔系统设置记录不是单纯靠“哪个包排前面”决定的。Settings.Secure.HOME_CURRENT就是记录默认桌面组件的地方。你在设置里的“主屏幕应用”里切换改的也是这个值。所以在做屏蔽操作时必须同步处理这个旧记录。只把原生 Launcher 的 HOME 属性摘掉但没有把HOME_CURRENT里的旧分量清掉或改成自研 Launcher系统就会在“记录指向的组件已经不再匹配”和“需要寻找新的 Home”之间反复横跳报错就是这么来的。调试阶段可以直接用命令查看当前 Home 解析结果adb shell cmd package resolve-activity --brief -a android.intent.action.MAIN -c android.intent.category.HOME如果输出为空或者是 null说明系统当前状态下根本没有可用的 Home 候选。如果输出里还有原生 Launcher 的组件说明你的屏蔽没有真正生效。4. 屏蔽 HOME 属性的三种主流做法与工程取舍4.1 方案一改原生 Launcher 的 Manifest从源头摘掉 HOME 属性这是最直接的“物理屏蔽”。前提是你手里有 AOSP 源码或者至少能改到预置 APK 的资源。定位到packages/apps/Launcher3/AndroidManifest.xml在 Launcher Activity 的 intent-filter 里把 HOME category 注释掉或删掉。需要注意删掉 HOME 属性之后这个 Activity 就不再是系统桌面候选了。但如果系统里没有其他带 HOME 属性的应用开机就回不了家。所以这个方案必须搭配一个前提自研 Launcher 的 Manifest 要同时保证action MAIN、category HOME、category DEFAULT三个条件都满足。这种做法的好处是干干净净在 Parser 层面就不认为原生 Launcher 是桌面后续所有系统服务的查询结果自然不会有它。缺点是每一台机器都得重新预置镜像如果产品线已经铺开了改起来成本不小。4.2 方案二在 PackageManagerService 对 HOME 候选做包名过滤另一种做法是在系统服务层过滤。项目上线后发现不想动 APK或者原生 Launcher 的源码包不方便改就可以在 PMS 的查询结果里把指定包名从 Home 候选列表里剔除。以 Android 10 的PackageManagerService代码为参考处理思路是在queryIntentActivitiesInternal返回结果前做一次包名过滤。示意代码如下private ListResolveInfo maybeFilterHomeResolveList(ListResolveInfo resolveInfos, Intent intent) { // 只处理 ACTION_MAIN CATEGORY_HOME 的查询 if (!Intent.ACTION_MAIN.equals(intent.getAction()) || !intent.hasCategory(Intent.CATEGORY_HOME)) { return resolveInfos; } String ignoredPkg SystemProperties.get(ro.kiosk.ignore_home_pkg, ); if (TextUtils.isEmpty(ignoredPkg)) { return resolveInfos; } ListResolveInfo filtered new ArrayList(resolveInfos.size()); for (ResolveInfo info : resolveInfos) { if (!ignoredPkg.equals(info.activityInfo.packageName)) { filtered.add(info); } } return filtered; }这里的核心思路是用一个系统属性或者配置文件来控制“哪个包不再参与 Home 候选”。好处是不用重新编译 Launcher APK而且把条件做成开关之后想恢复原生 Launcher 的桌面资格改一行属性重启就行非常适合产品版本迭代期间做 A/B 验证。坏处也很明显改的是 PMS 这个核心服务影响面比改 APK 大得多。所有调用queryIntentActivities(ACTION_MAIN CATEGORY_HOME)的模块都会受影响包括 Settings 的“主屏幕应用”、LauncherAppsService、SystemUI。所以在过滤 PMS 结果的同时必须同步处理上面说的HOME_CURRENT失效记录和 Settings 判空逻辑否则过滤生效后照样会崩。4.3 方案三曲线思路——保留属性但让自研 Launcher 接管严格来说这不算“屏蔽 HOME 属性”而是利用 Android 已有的“默认 Home 绑定”机制把系统对 Home 的解析结果固定到自研 Launcher。在设备企业版或者设备所有者模式下可以用DevicePolicyManager.addPersistentPreferredActivity()把ACTION_MAIN CATEGORY_HOME这个 Intent 持久化绑定到自研 Launcher 的某个 ActivityDevicePolicyManager dpm getSystemService(DevicePolicyManager.class); ComponentName admin getAdminComponentName(); Intent homeIntent new Intent(Intent.ACTION_MAIN); homeIntent.addCategory(Intent.CATEGORY_HOME); dpm.addPersistentPreferredActivity( admin, homeIntent, new ComponentName(com.example.kiosk, .MainActivity));这样系统在解析 Home 候选时会优先且直接使用自研 Launcher不会再弹“选择主屏幕应用”对话框原生 Launcher 即使保留 HOME 属性也没有机会被默认选中。这个方案的好处是改动最小甚至不需要重新编译系统镜像只要在设备初始化流程里设置一次 Device Owner 即可。缺点是它依赖 DPM 机制设备必须进入 Device Owner 或 Profile Owner 状态而且原生 Launcher 仍然保留着 HOME 属性只是系统不再默认选它。如果后续有人通过设置把默认桌面切回去原生 Launcher 还是可能被调起。4.4 三个方案的对比与选择建议维度源码改 ManifestPMS 过滤 属性开关DPM 持久化默认 Home改动位置Launcher APK 源码framework 系统服务设备管理器配置是否重新编译镜像是是否可在运行时设置是否影响 PMS 查询结果是是间接解析时优先走预设组件恢复默认原生 Launcher需要重新编译改开关属性重启移除持久化规则风险等级中高低量产稳定性高中高我的建议是如果你的产品线还没有量产优先用方案三用 DPM 把默认 Home 钉到自研 Launcher成本最低回滚最容易。如果项目不允许设备进入 Device Owner 模式再考虑方案一反正整机方案都会重新预置镜像改 Manifest 最直观。方案二适合那种“东西已经铺出去了只能在线升级 framework”的场景但一定要把 PMS 过滤带来的连锁问题想清楚否则改完还不如不改。5. 报错修复逐个击破稳住框架层再收拾应用层5.1 开机黑屏、按 HOME 键没反应startHomeActivity 路径上的兜底处理先看现象。设备屏蔽原生 Launcher 的 HOME 属性且没有其他可解析的 Home 候选时系统日志会出现类似这样的内容ActivityTaskManager E startHomeActivityLocked: No home activity found, device will stay in boot animation这条日志说明系统尝试启动桌面时失败了开机流程停在这里。修复的第一步不是去改 framework而是先确认你到底需不需要保留一个 Home如果产品形态是“开机必须进入自研全屏应用”那自研 Launcher 必须带MAIN HOME DEFAULT三个条件并用cmd package resolve-activity验证。如果产品形态是“开机直接进单一应用确实不需要传统桌面”那就得在 framework 里加一个兜底 Home Activity否则开机流程没法结束。给后一种情况打个比方系统开机流程就像一个人深夜回家如果发现门锁换掉了他需要的是另一把能开门的钥匙而不是在门口干等着。兜底 Home Activity 就是这把备用钥匙。具体做法是在系统源码里新增一个极简 Activity比如FallbackHomeActivity它不做任何界面启动后立即把任务转到自研主界面。然后在ActivityTaskManagerService里当resolveHomeActivity()返回 null 时把启动目标切到FallbackHomeActivity。这里给一段示意逻辑private void startHomeActivityLocked(int userId, String reason) { ResolveInfo homeResolve resolveHomeActivity(userId); if (homeResolve null) { Slog.w(TAG, No home found, starting FallbackHome); Intent fallback new Intent(); fallback.setComponent(new ComponentName(com.android.systemui, com.android.systemui.FallbackHome)); mActivityStartController.startActivity( fallback, /* caller */ null, /* ... */); return; } // 原有的正常启动 Home 逻辑 }不同厂商的 AOSP 分支这个函数的名字和位置可能不一样但思路一致在“找不到 Home”这个分支上给出降级方案而不是让系统卡死在开机动画里。排查这类问题时我建议按这个顺序走adb logcat抓开机日志确认是不是startHomeActivityLocked在刷错误。执行cmd package resolve-activity看当前 Home 候选到底有谁。用dumpsys package查被屏蔽包的组件状态确认是不是 PMS 或 manifest 层面确实没匹配上。根据产品需求决定补自研 Launcher 的 HOME 属性还是挂兜底 Activity。5.2 Settings“主屏幕应用”为空PreferenceController 判空与隐藏Settings 崩溃的原因多半是旧默认桌面记录失效。排查链路如下先看崩溃日志里的调用栈确认是DefaultHomePreferenceController在getDefaultHomeIntent()里拿到 null 后直接访问字段。再执行adb shell settings get secure home_current如果输出里还是com.android.launcher3/.Launcher这种旧分量而原生 Launcher 的 HOME 属性已经被屏蔽那 Settings 在解析时必然拿不到结果。修复分两步第一步在 Settings 代码里给DefaultHomePreferenceController增加判空保护。大致逻辑是ResolveInfo resolveInfo mPackageManager.resolveActivityAsUser( homeIntent, PackageManager.MATCH_DEFAULT_ONLY, userId); if (resolveInfo null) { preference.setVisible(false); return; }也就是当系统没有任何可用的 Home 候选时干脆把“主屏幕应用”这个入口隐藏掉而不是让用户点进去崩溃。如果你的产品本身就不需要用户去改默认桌面这个方案最直接。第二步清理系统里失效的默认桌面记录。比较稳妥的做法是在 PMS 过滤逻辑或设备初始化脚本里把home_current改为自研 Launcheradb shell settings put secure home_current com.example.kiosk/.MainActivity或者直接删掉让系统重新走一次 Home 解析adb shell settings delete secure home_current在新机器量产时应该在出厂镜像初始化脚本里就把这个值写好不要等用户开机之后再处理。5.3 隐式调用 HOME Intent 的第三方应用统一容错与降级方案屏蔽 HOME 属性之后除了系统自身的模块还可能被第三方应用炸到。典型场景是某个应用通过隐式 Intent 请求回到桌面Intent homeIntent new Intent(Intent.ACTION_MAIN); homeIntent.addCategory(Intent.CATEGORY_HOME); startActivity(homeIntent);在没有 Home 候选或者候选被过滤掉的情况下startActivity就会抛ActivityNotFoundException。第三方应用如果不捕获异常直接崩溃。这类问题的修复原则是不要指望所有第三方应用都做容错你要么保证系统里永远有一个可用的 Home 候选要么就得在调用链路里兜底。对于自己可控的系统应用或系统服务建议统一改成“先解析再启动”并在失败时降级到自研 Launcher 的显式 IntentIntent homeIntent new Intent(Intent.ACTION_MAIN); homeIntent.addCategory(Intent.CATEGORY_HOME); ResolveInfo info getPackageManager().resolveActivity(homeIntent, PackageManager.MATCH_DEFAULT_ONLY); if (info ! null) { startActivity(homeIntent); } else { Intent fallback new Intent(); fallback.setComponent(new ComponentName(com.example.kiosk, .MainActivity)); startActivity(fallback); }在整机源码里可以通过搜索“CATEGORY_HOME”把所有调用方找出来逐个评估grep -r android.intent.category.HOME packages/ vendor/ frameworks/base/ --include*.java | grep -v test重点看两个地方一是谁在构造 HOME Intent二是有没有在startActivity附近加 try/catch。凡是这种隐式调用一律补上异常捕获避免某个入口因为找不到桌面而崩溃。6. 部署、验证与一套管用的调试命令6.1 修改 framework 后的正确替换与 oat 缓存处理如果你采用的是 PMS 过滤或兜底 Home 这类 framework 改动改完代码后替换文件这一步很容易踩坑。Android 10 上替换services.jar或者framework.jar后如果不清除 oat 缓存系统会继续加载旧的编译产物你的代码改了等于没改。比较稳的操作流程是# 进入 userdebug 版本先禁用 dm-verity否则 /system 只读 adb root adb disable-verity # 部分 Android 10 机器需要用新命令 adb shell avbctl disable-verification adb reboot # 重启后挂载可写 adb remount # 替换 framework 相关文件 adb push out/target/product/xxx/system/framework/services.jar /system/framework/ adb push out/target/product/xxx/system/framework/framework.jar /system/framework/ # 删除 oat 缓存强制重新编译 adb shell rm -rf /system/framework/oat /system/framework/arm /system/framework/arm64 adb reboot这里有三个细节值得记住disable-verity和avbctl disable-verification的区别在于部分 Android 10 机型使用 AVBdisable-verity已经不生效优先用avbctl那条。如果只是替换 APK不需要手动清 oatpm install会自动处理。替换 framework 文件后第一次开机会比较慢因为系统在重新做 AOT 编译不要以为是卡死直接拔线。6.2 回归用例清单哪些项目必须测过才敢交付屏蔽 HOME 属性不是改完代码拉起来看一眼就完事必须跑回归。下面是我在一个项目里实际用过的用例清单按照优先级排列序号测试项预期结果1冷启动进入自研界面无“选择主屏幕应用”弹窗不黑屏2重启后按 HOME 键立即回到自研 Launcher无延迟无崩溃3无任何 Home 候选时系统有兜底页面不卡开机4Settings - 默认应用 - 主屏幕应用正常显示或隐藏点击不崩溃5最近任务/手势导航能切到自研 Launcher 或明确降级6锁屏/壁纸/截屏正常不依赖原生 Launcher7第三方应用发 HOME 隐式 Intent不崩溃或降级到自研 Launcher8恢复出厂设置默认桌面仍指向自研 Launcher这里最容易翻车的是第 5 项。很多自研 Launcher 并没有实现 QuickStep 协议屏蔽原生 Launcher 之后用户从底部上滑呼出最近任务可能直接没反应或者闪一下。遇到这种情况要么自研 Launcher 补齐 QuickStep 实现要么在产品需求里明确“设备不支持手势导航使用三键导航”并做好对应配置。6.3 再次强调的几点经验与注意事项调试这类问题我个人的习惯是先把“Home 解析结果”验证干净再做其他事情。全部问题排查完有几点经验是写在代码注释里也提醒不了的第一不要一边屏蔽 HOME 属性一边又不留任何 Home 候选。系统无论开机还是按 HOME 键都需要一个地方去。如果你真的不需要传统桌面就挂一个空的兜底 Home至少让系统流程能走通。第二PMS 层的过滤要加上可逆开关。我见过太多团队直接把过滤逻辑写死在 PMS 里后面又想恢复原生 Launcher 桌面资格结果只能重新出镜像。用SystemProperties做黑名单比写死包名灵活得多出问题还能远程关掉。第三Settings.Secure.HOME_CURRENT这个过期状态一定要处理。很多崩溃的根源其实不在屏蔽本身而在“系统还记着一个已经失效的默认桌面”。清理旧记录或者预置新记录应该成为整个方案的一部分而不是等崩了再修。第四只有带MAIN HOME DEFAULT的 Activity 才有资格当桌面。改 Manifest 的时候不要把 DEFAULT 删掉否则你可能以为自己成功屏蔽了实际上只是让解析结果为空症状会特别难排查。最后再补一句这类定制问题没有捷径。每一次改完系统服务都用adb logcat -b crash从头抓一遍日志把每个ActivityNotFoundException和NullPointerException串起来看你才能确定到底是哪一环漏了。把开机、HOME 键、设置入口这三个主要路径跑通剩下的就是细节了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑