如果更新或者升级后系统内置应用,遇到重启Android系统后内置应用被还原,那是因为手动安
装的APK版本号和系统内置API版本号一样。
1、Android系统应用更新机制
系统为每个应用在AndroidMainfest.xml提供了versionName、versionCode两个属性。
versionName:String类型,用来给应用的使用者来查看版本.
versionCode:Integer类型,作为系统判断应用是否能升级的依据。
2、Android系统内置应用更新判断代码
代码来自frameworks/base/services/java/com/android/server/PackageManagerService.java 中 scanPackageLI函数的package更新判断条件
从上面代码注释可以知道:更新系统内置应用时,如果新的versionCode没有大于当前安装的 版本,更新将被忽略。
3、开发者误区
对Android应用更新机制不熟悉的开发者,错误地把versionName作为应用更新的依据,以致 于在更新程序出现一些问题:
1、更新程序设计时必须把versionName设置小数形式,如2.1,当设置为2.2.1时程序就不好判 断是否该更新版本。
1、Android系统应用更新机制
系统为每个应用在AndroidMainfest.xml提供了versionName、versionCode两个属性。
versionName:String类型,用来给应用的使用者来查看版本.
versionCode:Integer类型,作为系统判断应用是否能升级的依据。
2、Android系统内置应用更新判断代码
代码来自frameworks/base/services/java/com/android/server/PackageManagerService.java 中 scanPackageLI函数的package更新判断条件
//如果是系统安装包
if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
//如果apk的路径已经更改
if (ps != null && !ps.codePath.equals(scanFile)) {
//判断当前apk版本号是否小于原始版本
if (pkg.mVersionCode < ps.versionCode) {
// 系统包已经是最新版本,且安装路径不匹配,忽略
mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
return null;
} else {
//更新安装包到系统分区中
synchronized (mPackages) {
// 从PackageManagerService的安装包列表中删除该包
mPackages.remove(ps.name);
}
//创建安装参数InstallArgs
InstallArgs args = createInstallArgs(packageFlagsToInstallFlags(ps),
ps.codePathString, ps.resourcePathString, ps.nativeLibraryPathString);
synchronized (mInstaller) {
//清空dex文件及安装包的挂载点
args.cleanUpResourcesLI();
}
synchronized (mPackages) {
mSettings.enableSystemPackageLPw(ps.name);
}
}
}
}
从上面代码注释可以知道:更新系统内置应用时,如果新的versionCode没有大于当前安装的 版本,更新将被忽略。
3、开发者误区
对Android应用更新机制不熟悉的开发者,错误地把versionName作为应用更新的依据,以致 于在更新程序出现一些问题:
1、更新程序设计时必须把versionName设置小数形式,如2.1,当设置为2.2.1时程序就不好判 断是否该更新版本。
2、可能导致系统内置应用无法升级,不断被还原。
如果升级Android内置apk版本,遇到系统重启后又被还原,那是因为你手动安装的apk版本号和内置系统的apk版本号一样。
这样的情况,在开发调试系统apk的情况中容易出现。
关于Android系统内置的apk更新后,在系统重启以后又被还原的问题,解决方法如下:
将 frameworks/base/services/java/com/android/server/PackageManagerService.java 中 scanPackageLI函数的package更新判断条件
if (pkg.mVersionCode < ps.versionCode) {
修改为
if (pkg.mVersionCode <= ps.versionCode) {