【Android】非System用户下Persist应用不自动拉起

非System用户下Persist应用不自动拉起

  • Android版本:11、12。

背景

  • 先说结论:Android在多用户场景下,系统不会启动非User 0(System)的Persist应用

应用A配置了Persist应用,且无android:singleUser=true配置。但在多用户环境下,只启动了system(user 0)进程。
排查怀疑点

  • pm list package --user userID: 查看应用A在对应的用户下是否安装
  • /data/system/user/userID/package-restrcition.xml:查看应用A是否有异常信息。

排查上述两点问题后,发现应用A在对应的userID下已经安装。

  • 尝试手动启动应用,发现可以启动。且手动kill后,可以被Aosp作为Persist应用重新拉起。
# 在User X下启动Service
am startservice --user X-n com.***.A/com.***.A.AService
# 在User X下启动Activity
am start  --user X-n com.***.A/com.***.A.AActivity

问题原因

Aosp的多用户管理模块中UserController.java,非User 0(System)下,默认不会拉起Persist应用。
在这里插入图片描述
在finishUserUnlocked的函数中。判断了,只有UserID为USER_SYSTEM的,才会启动Persist类型且“android:directBootAware=false”的应用。

如何解决这个问题

  • 监听开机广播、或者其他广播做自启动
  • 或者尝试修改Aosp代码
<think>好的,我现在需要回答用户的问题:如何在Android设备恢复出厂设置时保留persist.sys相关的数据。首先,我得理解persist分区的特性。在Android系统中,persist分区通常用于存储持久性数据,这些数据在恢复出厂设置时默认会被清除。过,用户可能遇到特殊情况,需要确保某些数据确实保留。 接下来,我需要考虑系统恢复出厂设置的流程。恢复出厂设置一般会清除/data和/cache分区,但会影响/persist过,如果用户发现persist数据被删除了,可能有其他因素,比如自定义的恢复脚本或特定厂商的实现。 然后,我应该检查系统源码中与恢复出厂设置相关的部分。例如,在Settings应用中,恢复出厂设置的代码可能调用MasterClearReceiver或RecoverySystem类。需要确认这些流程是否包含对persist分区的操作。例如,查看RecoverySystem.java中的clearWipeData()方法是否调用了格式化persist分区的命令。 另外,用户提到的removeDataDirsLI函数可能属于PackageManagerService,用于删除应用数据。但persist数据通常在这里处理,所以这可能相关。过,需要确认是否有其他服务或脚本在恢复过程中操作persist分区。 接下来,可能的解决方案包括修改系统源码或使用自定义恢复工具。修改源码的话,需要找到触发恢复出厂设置的代码位置,并移除任何涉及persist分区的操作。例如,在RecoverySystem中,确保wipe命令包含persist。或者,在init.rc脚本中,检查是否有恢复时格式化persist的指令。 如果用户没有源码权限,可以考虑通过adb在恢复前备份persist数据,恢复后再还原。这需要root权限,并且可能涉及dd命令或备份工具。此外,检查是否有系统属性控制persist分区的处理,例如在build.prop中添加配置。 还需要考虑同厂商的定制情况。例如,某些厂商可能在恢复过程中加入额外的清理步骤,因此需要具体分析设备的实现。用户提到的全志芯片设备可能有同的分区策略,需参考具体文档。 最后,需要提醒用户操作风险,修改系统分区可能导致设备变砖,建议谨慎操作并备份数据。同时,测试任何修改前应充分了解设备的具体情况。</think>在Android设备上恢复出厂设置时保留$persist.sys$相关数据,需根据系统分区特性及恢复机制进行调整。以下为具体实现路径: ### 一、persist分区特性分析 1. **持久性存储特性**:$persist$分区专为存储跨重启保留的数据设计,默认恢复出厂设置会清除该分区[^2] 2. **系统级保护机制**:原生Android恢复流程仅清除$data$和$cache$分区,但部分厂商定制ROM可能包含特殊处理逻辑 ### 二、关键技术实现方案 #### 方案一:修改恢复出厂设置源码 1. 定位恢复出厂设置入口类: ```java frameworks/base/services/core/java/com/android/server/MasterClearReceiver.java frameworks/base/core/java/android/os/RecoverySystem.java ``` 2. 拦截分区擦除指令: ```java // 修改RecoverySystem类的clearWipeData()方法 public static void clearWipeData(boolean shutdown) { String cmd = "wipe_data\n--preserve_persist\n"; // 新增保留persist参数 bootCommand(context, cmd); } ``` #### 方案二:调整文件系统挂载配置 在$fstab$文件中标记persist分区为可擦除: ```bash # device/<manufacturer>/<codename>/fstab.<hardware> /dev/block/bootdevice/by-name/persist /persist ext4 noatime,nosuid,nodev,barrier=1,noauto_da_alloc,nomerge wait,check,formattable=never # 关键参数 ``` #### 方案三:Hook系统服务 通过Xposed模块拦截数据清除操作: ```java XposedHelpers.findAndHookMethod("android.os.RecoverySystem", lpparam.classLoader, "clearWipeData", boolean.class, new XC_MethodHook() { protected void beforeHookedMethod(MethodHookParam param) { String originalCmd = (String) XposedHelpers.getObjectField(param.thisObject, "mCommand"); param.thisObject.setObjectField("mCommand", originalCmd.replace("wipe_persist", "")); } }); ``` ### 三、厂商定制系统应对策略 针对引用[2]提到的全志芯片设备,需特别注意: 1. 检查$vendor/partition/cleanup.sh$擦除脚本 2. 修改厂商自定义恢复组件: ```bash # 典型厂商擦除脚本片段 for part in system data cache; do make_ext4fs /dev/block/${part} # 移除persist分区处理 done ``` ### 四、验证与调试 1. 使用adb监控恢复过程: ```bash adb shell dmesg | grep -E 'wipe|persist' ``` 2. 验证persist数据保留: ```bash adb shell "ls -l /persist/sys && getprop persist.sys.*" ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值