web-dev-qa-db-fra.com

Application système avec Android: persistent = true se bloque après la mise à jour

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)?

13
user3118604

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.

2
satur9nine

Trouvé une solution de contournement pour le problème. La mise à jour réussit si la nouvelle version change de nom de processus.

0
user3118604

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).

0
David Lev