带有android的系统应用程序:持久性=true更新后崩溃

2022-09-03 08:03:11

我有一个系统特权的应用程序,其中android:persistent=true<应用程序>。当我更新它(通过ADB或任何其他方式)时,它无法正确更新并崩溃。

我看到的是,系统在当前(系统安装的)版本仍在运行时安装更新。在更新过程中,系统不会停止该过程(尝试停止并失败或根本不尝试)。更新完成后,应用程序似乎正在经历“重新启动” - 我看到组件正在初始化,例如应用程序::onCreate()被调用。但这发生在与更新之前相同的过程中!

因此(在启动应用程序的某些活动时),应用程序崩溃并出现“奇怪”的异常,例如无法将类强制转换为自身:

Caused: java.lang.ClassCastException: com.二十年新浪网.类名不能强制转换为 com。二十年新浪网.类名

在调查时,我看到更新后使用的ClassLoader并不是指更新后的APK的路径,而是仍然指向原始版本的路径:

预期的类装入器:

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]]]

实际类装入器:

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上发布较新版本)?


答案 1

使用系统映像中的应用时不能使用,并且持久性应用必须位于系统映像中。您正在为哪个版本的Android开发?在最新版本的Android上,我使用下面描述的方法之一。在每一个之前,您必须至少运行一次。adb installadb remount

方法 1:仅适用于代码更改,不适用于资源更改或清单更改

暂时将其添加到您的:Android.mk

LOCAL_DEX_PREOPT := false # Do not commit

然后执行构建或类似操作。mm

运行相应的推送命令,如下所示:

adb push $OUT/system/priv-app/MyApp/MyApp.apk /system/priv-app/MyApp/

由于应用是持久的,因此必须使用以下命令终止应用进程,以便它获取更改:

adb shell ps | grep com.my.app | awk '{print $2}' | xargs adb shell kill

不要忘记删除或注释掉在提交或进行完整构建之前所做的更改。Android.mk

方法2:除了简单的java代码更改之外,其他任何事情都是必需的

执行构建或类似操作。mm

运行以下命令:

adb sync
adb shell stop
adb shell start

方法 3

只是为了完整性,您可以构建整个树,然后刷新系统或从结果中应用OTA。


答案 2

您可以使用简单的 hack 和 注册 来接收设备上安装的每个应用程序的“android.intent.action.PACKAGE_ADDED”意图。如果添加的应用程序具有你的程序包 ID(指示你的应用已更新),你可以尝试强制它完成,并等待“持久”机制将其重新作为新进程重新加入。

请注意,我一直在多个平台上使用持久性应用程序,并且从未见过您描述的行为(如果可以提供您正在使用的平台,可能会有所帮助)。


推荐