Android11.0 应用升级成功后立即断电重启,版本恢复
问题:客户反馈内置的应用升级成功后立刻断电重启,应用的版本被恢复。
使用adb命令升级客户应用,查看版本显示已更新,/data/system目录下packages.xml和packages.xml中应用版本信息均已更新
C:\Users\dell>adb shell dumpsys package com.xxx.xxx | findstr versionversionCode=85 minSdk=21 targetSdk=28versionName=1.0.1.0signatures=PackageSignatures{d02434f version:2, signatures:[b414bf3f], past signatures:[]}versionCode=6 minSdk=21 targetSdk=28versionName=1.0.0.5signatures=PackageSignatures{9ec2ba version:0, signatures:[], past signatures:[]}C:\Users\dell>
立刻断电重启,结果是应用版本恢复为升级前,packages.xml和packages.xml中应用版本也恢复为升级前。
抓取开机时的部分log
D PackageManager: Scanning app dir /system/app scanFlags=66064 flags=0x10
D PackageParser2: Parse times for '/system/app/Huaxinan': parse=103ms, update_cache=16 ms
D PackageManager: updatedPkg = PackageSetting{dd36952 com.hxa.liquorDetection/10072}
W PackageManager: Failed to scan /system/app/Huaxinan: Package com.hxa.liquorDetection at /system/app/Huaxinan ignored: updated version 85 better than this 6
D PackageParsing: Scanning base APK: /system/app/SimAppDialog/SimAppDialog.apk
...
D PackageManager: Scanning app dir /data/app scanFlags=656 flags=0x0
D ziparchive: Zip: EOCD not found, /data/app/~~hS4pBWf_EmJVWTN5yccvXQ==/com.hxa.liquorDetection-o9M5-Vj2rJ5jU9C3I1VFYw==/base.apk is not zip
E system_server: Failed to open APK '/data/app/~~hS4pBWf_EmJVWTN5yccvXQ==/com.hxa.liquorDetection-o9M5-Vj2rJ5jU9C3I1VFYw==/base.apk' Invalid file
W PackageManager: Failed to parse /data/app/~~hS4pBWf_EmJVWTN5yccvXQ==: Failed to parse /data/app/~~hS4pBWf_EmJVWTN5yccvXQ==/com.hxa.liquorDetection-o9M5-Vj2rJ5jU9C3I1VFYw==/base.apk
W PackageManager: Deleting invalid package at /data/app/~~hS4pBWf_EmJVWTN5yccvXQ==
D PackageParsing: Scanning base APK: /data/app/~~TLEO_8XLgBa_y0O5XZ_ztA==/com.hxa.liquorDetection-10KwjrAku4e5aF7CKZiI9A==/base.apk
D PackageManager: updatedPkg = PackageSetting{dd36952 com.hxa.liquorDetection/10072}
I PackageManager: /data/app/~~TLEO_8XLgBa_y0O5XZ_ztA==/com.hxa.liquorDetection-10KwjrAku4e5aF7CKZiI9A== changed; collecting certs
W PackageManager: Relax SCAN_REQUIRE_KNOWN requirement for package com.hxa.liquorDetection
I PackageManager: Update system package com.hxa.liquorDetection code path from /data/app/~~hS4pBWf_EmJVWTN5yccvXQ==/com.hxa.liquorDetection-o9M5-Vj2rJ5jU9C3I1VFYw== to /data/app/~~TLEO_8XLgBa_y0O5XZ_ztA==/com.hxa.liquorDetection-10KwjrAku4e5aF7CKZiI9A==; Retain data and using new
I PackageManager: Update system package com.hxa.liquorDetection resource path from /data/app/~~hS4pBWf_EmJVWTN5yccvXQ==/com.hxa.liquorDetection-o9M5-Vj2rJ5jU9C3I1VFYw== to /data/app/~~TLEO_8XLgBa_y0O5XZ_ztA==/com.hxa.liquorDetection-10KwjrAku4e5aF7CKZiI9A==; Retain data and using new
I PackageManager: Finished scanning non-system apps. Time: 172 ms, packageCount: 2 , timePerPackage: 86 , cached: 0
- 源码:frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {// The version of the application on the /system partition is less than or// equal to the version on the /data partition. Throw an exception and use// the application already installed on the /data partition.throw new PackageManagerException(Log.WARN, "Package " + parsedPackage.getPackageName()+ " at " + parsedPackage.getCodePath() + " ignored: updated version "+ pkgSetting.versionCode + " better than this "+ parsedPackage.getLongVersionCode());
}
...
if (throwable == null) {// TODO(toddke): move lower in the scan chain// Static shared libraries have synthetic package namesif (parseResult.parsedPackage.isStaticSharedLibrary()) {renameStaticSharedLibraryPackage(parseResult.parsedPackage);}try {addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags,currentTime, null);} catch (PackageManagerException e) {errorCode = e.error;Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());}
} else if (throwable instanceof PackageParserException) {PackageParserException e = (PackageParserException)throwable;errorCode = e.error;Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage())
} else {throw new IllegalStateException("Unexpected exception occurred while parsing "+ parseResult.scanFile, throwable);
}
结合log和源码 看是解析/system/app/Huaxinan下的apk时,发现有新的版本85比6版本更好,然后抛出一个PackageManagerException异常,选择使用/data分区上的版本;
接着到扫描/data/app目录,log显示解析文件失败抛出一个PackageParserException的异常,错误码是INSTALL_PARSE_FAILED_NOT_APK,接着扫描/data/app下应用另一个版本目录。
看到此处的log有点怀疑是不是应用缓存没有清除或者哪里没有同步,在应用升级成功后/data/app下只看到当前版本的相关文件,并没有第二个此应用目录文件。
验证是否是缓存没有清除导致
①命令重启设备
adb install -r new.apk
adb reboot
设备重启后应用版本显示正常
②清除应用缓存
adb install -r new.apk
adb shell
pm clear com.hxa.liquorDetection
直接断电重启设备,应用版本显示正常。
最佳方式是使用同步,在应用安装成功后直接调用sync同步。
- 源码:frameworks/base/services/core/java/com/android/server/pm/PackageInstallerSession.java
private static void sendOnPackageInstalled(Context context, IntentSender target, int sessionId,boolean showNotification, int userId, String basePackageName, int returnCode,String msg, Bundle extras) {if (PackageManager.INSTALL_SUCCEEDED == returnCode && showNotification) {boolean update = (extras != null) && extras.getBoolean(Intent.EXTRA_REPLACING);Notification notification = PackageInstallerService.buildSuccessNotification(context,context.getResources().getString(update ? R.string.package_updated_device_owner :R.string.package_installed_device_owner),basePackageName,userId);if (notification != null) {NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);notificationManager.notify(basePackageName,SystemMessageProto.SystemMessage.NOTE_PACKAGE_STATE,notification);}}// add startfileSync();// add end...
}// add start
private static void fileSync(){Runtime runtime = Runtime.getRuntime();try {runtime.exec("sync");} catch (IOException e) {e.printStackTrace();android.util.Log.e(TAG, "fileSync"); }
}
// add end
编译后刷机,升级应用直接断电重启设备,应用版本显示正常.
android 设备写入文件,立即断电重启后,文件丢失,数据没有保存问题
apk安装提示 Zip: EOCD not found, /storage/emulated/0/Download/*.apk is not zip