Android AOSP更新system_ext分区持久化应用失败问题咨询
问题根因
两个报错分别对应系统的两层强制限制,和操作权限、apk签名正确性无关:
- adb push触发只读错误:Android正常运行状态下
/system_ext分区默认以只读模式挂载,直接向分区路径写入文件必然触发couldn't create file: Read-only file system报错。 - adb install触发更新失败:预置在priv-app路径下的TestService声明了
android:persistent="true"属性,这类常驻持久化系统应用属于系统核心组件范畴,PackageManagerService默认直接拦截所有常规安装渠道的更新请求,避免持久化进程运行异常导致系统稳定性问题。
可行解决方法
按调试阶段的便捷度从高到低排序:
方案1:重挂载分区后直接替换(最快,适合单次快速调试)
这是日常开发最常用的调试方式,不需要重烧完整镜像,仅支持userdebug/eng编译的工程镜像:
- 获取adb root权限:
adb root - 关闭分区校验,重启后重挂载系统分区为可读写:
adb disable-verityadb reboot
设备重启重连后,再次执行root和重挂载操作:adb rootadb remount
如果是Android 12及以上版本,adb remount未自动将system_ext挂为可读写,可手动执行挂载命令:adb shell mount -o rw,remount /system_ext - 推送新编译的apk到对应预置路径:
adb push TestService.apk /system_ext/priv-app/TestService/TestService.apk - 修正文件权限(避免系统读取apk失败):
adb shell chmod 644 /system_ext/priv-app/TestService/TestService.apk - 清理旧的dex缓存、重启设备让系统加载新apk:
adb shell rm -rf /data/dalvik-cache/*/system_ext@priv-app@TestService*adb shell reboot
如果不想整机重启,也可以执行adb shell pkill zygote重启zygote进程,加载速度更快,部分高版本系统可能存在权限限制
方案2:单独编译刷入system_ext分区(适合频繁迭代,环境一致性高)
如果不想修改分区挂载状态,保持和正式发布环境一致,可以只编译system_ext分区镜像单独刷入,不会擦除用户数据:
- 在AOSP源码根目录下,先编译目标应用模块,再生成system_ext分区镜像:
mmm packages/services/TestService/ -j$(nproc)make system_extimage -j$(nproc) - 设备进入fastboot模式单独刷入分区镜像:
adb reboot bootloaderfastboot flash system_ext $OUT/system_ext.imgfastboot reboot
方案3:临时关闭persistent属性(适合纯业务逻辑快速验证)
如果当前调试不需要验证应用持久化拉起、开机自启相关特性,可以临时把AndroidManifest.xml中的android:persistent="true"属性删除,编译出的apk可以直接通过adb install -r命令覆盖安装,调试完成后改回属性即可。
注意:该方案仅适合临时调试,非persistent状态的应用生命周期、进程优先级和正式状态存在差异,不要用该状态验证正式版本逻辑
注意事项
- 上述所有方案仅适用于userdebug/eng编译的工程调试设备,正式user版本默认关闭root权限、锁定分区校验,无法通过以上方式更新预置应用,正式版本必须走OTA整包/分区升级流程。
- 不要尝试添加
adb install -f、--bypass-low-target-sdk-block等参数绕过persistent应用的安装限制,系统层面对这类应用的更新拦截是硬编码逻辑,参数无法绕过。
内容的提问来源于stack exchange,提问作者dnguyen244
相关产品推荐
相关产品推荐

