背景描述
Android大版本升级,有一个系统应用因为需求修改包名变了,R升S之后,R上的用户操作数据和缓存数据丢失。
问题原因
因为包名改变,导致升级之后系统检测原包名不存在,删除了data/data/包名数据。
升级完之后,data/data数据都不存在了,apk内部无法读取旧数据
Log如下:
PackageManager: System package aaa.bbb.ccc no longer exists; it's data will be wiped
问题分析
frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java
构造方法中
if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
//如果包名不可用,会删掉data数据
logCriticalInfo(Log.WARN, "System package " + ps.name
+ " no longer exists; it's data will be wiped");
removePackageDataLIF(ps, userIds, null, 0, false);
}
不删除data数据方案
1、修改新的apk包名和老的一样
缺点:
修改包名涉及到修改比较多,整个apk内部包名引用都得用显示,xml不能省略包名使用.Activity。
和之前功能相关的外部调用全都要修改包名。
优点:
修改包名后,数据肯定不会被删除,可以直接操作旧数据进行逻辑功能
2、修改framework PMS代码,不删除指定包名的data数据
优点:
不用修改包名,涉及修改比较少。
缺点:
需要修改新apk加载逻辑,加载 data/data/旧包名 路径的数据。
3、创建一个和R包名一样的demo apk放进去
优点:
不用修改包名,涉及修改比较少。
不用考虑新apk加载data/data/旧包名 路径的数据的问题,可以让新的apk share数据出来。
缺点:
需要加载demo apk share的数据。
需要修改新apk加载逻辑,加载 demo share的数据。
方案2
frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java
if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
//判断是升级并且是升级到S版本,并且包名是旧apk的包名,不删除data数据。
if (mIsUpgrade && mIsPreSUpgrade && "com.aaa.bbb".equals(ps.name)){
logCriticalInfo(Log.WARN, "System package " + ps.name
+ " no longer exists; it's com.aaa.bbb data,don't wiped");
continue;
}
logCriticalInfo(Log.WARN, "System package " + ps.name
+ " no longer exists; it's data will be wiped");
removePackageDataLIF(ps, userIds, null, 0, false);
}