J'ai une application privilégiée système avec Android: persistent = true dans <application>. Lorsque je la met à jour (via ADB ou tout autre moyen), elle ne parvient pas à se mettre à jour correctement et tombe en panne.
Ce que je constate, c'est que le système installe la mise à jour alors que la version actuelle (installée sur le système) est toujours en cours d'exécution. Au cours de la mise à jour, le système n'arrête pas le processus (tente de s’arrêter et échoue ou ne tente pas du tout). Une fois la mise à jour terminée, l'application semble subir un "redémarrage" - des composants en cours d'initialisation, tels que Application :: onCreate (), sont en cours d'appel. Mais cela se produit sur le même processus qu'avant la mise à jour!
Par conséquent (lors du lancement d'une activité de l'application), l'application se bloque avec des exceptions "étranges" telles que l'échec de la conversion de la classe vers elle-même:
Causée par: Java.lang.ClassCastException: com.XX.YY.ZZ.ClassName ne peut pas être converti en com.XX.YY.ZZ.ClassName
Lors de l’examen, j’ai constaté que le ClassLoader utilisé après la mise à jour ne faisait pas référence au chemin du fichier APK mis à jour mais restait orienté vers le chemin de la version originale:
Classloader attendu:
dalvik.system.PathClassLoader [DexPathList [[fichier ZIP] "/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]]]
Chargeur de classe actuel:
dalvik.system.PathClassLoader [DexPathList [[fichier Zip "/ system/priv-app/Appname.apk"HERMING,NativeLibraryDirectories=[/system/lib64/Start, /system/priv-app/Appname.apk!/ lib/x86_64,/system/lib64,/vendor/lib64,/system/lib64,/vendor/lib64]]]
Je suppose que cela est dû au fait que le processus n'a pas été redémarré lors de la mise à jour.
Y a-t-il un moyen de mettre à jour une application avec persistent = true? Ou s’agit-il d’un comportement attendu, cette application ne peut pas être mise à jour par la procédure de mise à jour commune (par exemple, la publication d’une version plus récente sur Google Play)?
Vous ne pouvez pas utiliser adb install
lorsque vous travaillez avec des applications figurant dans l'image système, et les applications persistantes doivent figurer dans l'image système. Pour quelle version d'Android développez-vous? Sur les versions récentes d'Android, j'utilise l'une des méthodes décrites ci-dessous. Avant chaque, vous devez exécuter adb remount
au moins une fois.
Méthode 1: fonctionne pour les modifications de code uniquement, ne fonctionne pas pour les modifications de ressources ou les modifications manifestes
Ajoutez temporairement ceci à votre Android.mk
:
LOCAL_DEX_PREOPT := false # Do not commit
Effectuez ensuite une construction avec mm
ou similaire.
Exécutez la commande Push appropriée comme suit:
adb Push $OUT/system/priv-app/MyApp/MyApp.apk /system/priv-app/MyApp/
Parce que l'application est persistante, vous devez tuer le processus de l'application à l'aide de la commande suivante pour qu'il enregistre les modifications:
adb Shell ps | grep com.my.app | awk '{print $2}' | xargs adb Shell kill
N'oubliez pas de supprimer ou de commenter la modification apportée à Android.mk
avant de valider ou de créer des versions complètes.
Méthode 2: nécessaire pour autre chose que de simples modifications de code Java
Effectuer une construction avec mm
ou similaire.
Exécutez les commandes suivantes:
adb sync
adb Shell stop
adb Shell start
Méthode 3
Juste pour être complet, vous pouvez simplement construire l’arbre entier et flasher le système ou appliquer un OTA à partir du résultat.
Trouvé une solution de contournement pour le problème. La mise à jour réussit si la nouvelle version change de nom de processus.
Vous pouvez utiliser un simple hack et vous enregistrer pour recevoir une intention "Android.intent.action.PACKAGE_ADDED" pour chaque application installée sur le périphérique. Dans le cas où l'application ajoutée a votre ID de package (indiquant que votre application a été mise à jour), vous pouvez essayer de la forcer à terminer et d'attendre que le mécanisme de "persistance" le reprenne en tant que nouveau processus.
Veuillez noter que j'utilise des applications persistantes sur plusieurs plates-formes et que je n'ai jamais observé de comportement tel que celui que vous décrivez (il pourrait être utile de fournir la plate-forme que vous utilisez).