我的发现是,系统在当前(已安装的系统)版本仍在运行时安装更新。在更新期间,系统不会停止进程(要么试图停止但失败,要么根本不尝试)。更新完成后,该应用似乎进行了“重启” - 我看到组件正在初始化,例如调用Application :: onCreate()。但这是在更新之前相同的进程上发生的!
因此(在启动应用程序的某些活动时),应用程序会出现“奇怪”的异常,例如无法将类强制转换为自身:
Caused by: java.lang.ClassCastException: com.XX.YY.ZZ.ClassName 无法转换为 com.XX.YY.ZZ.ClassName
在调查时,我发现更新后使用的ClassLoader不引用更新后APK的路径,而是仍然指向原始版本的路径:
预期的 classloader:
dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.app.package-1/base.apk"],nativeLibraryDirectories=[/data/app/com.app.package-1/lib/x86_64, /data/app/com.app.package-1/base.apk!/lib/x86_64, /system/lib64, /vendor/lib64]]]
实际 classloader:
dalvik.system.PathClassLoader[DexPathList[[zip file "/system/priv-app/Appname.apk"],nativeLibraryDirectories=[/system/lib64/Start, /system/priv-app/Appname.apk!/lib/x86_64, /system/lib64, /vendor/lib64, /system/lib64, /vendor/lib64]]]
我假设这是由于更新期间未重新启动进程而导致的。
有没有一种方法可以使用persistent=true更新应用程序?还是它是预期的行为,这种应用程序无法通过常规更新过程(例如在Google Play上发布新版本)进行更新?
adb shell stop
,然后再执行adb shell start
。对于最终用户的更新,您可能需要将应用程序拆分为一个真正的系统组件,通过恢复系统在 Android 未运行时应用的 system OTA 机制进行更新,以及一个更常见的应用程序组件,您可以通过 Play 商店进行更新。 - Chris Stratton