web-dev-qa-db-ja.com

Android:persistent = trueのシステムアプリが更新後にクラッシュする

<application>にAndroid:persistent = trueのシステム特権アプリがあります。 (ADBまたはその他の方法で)更新すると、正しく更新できず、クラッシュします。

私が見ているのは、現在の(システムにインストールされた)バージョンがまだ実行されている間に、システムがアップデートをインストールすることです。更新中、システムはプロセスを停止しません(停止を試みて失敗するか、まったく試行しません)。更新が完了した後、アプリは「再起動」しているようです。Application:: onCreate()などのコンポーネントが初期化されているのがわかります。しかし、これは更新前と同じプロセスで発生しています!

その結果(アプリのアクティビティを起動すると)、クラスをそれ自体にキャストできないなどの「奇妙な」例外でアプリがクラッシュします。

原因:Java.lang.ClassCastException:com.XX.YY.ZZ.ClassNameをcom.XX.YY.ZZ.ClassNameにキャストできません

調査中に、更新後に使用された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に新しいバージョンを投稿する)によって?

14
user3118604

システムイメージ内にあるアプリを操作する場合はadb installを使用できません。また、永続的なアプリはシステムイメージ内にある必要があります。どのバージョンのAndroidを開発していますか?最近のバージョンのAndroidでは、以下に説明する方法の1つを使用します。それぞれの前にadb 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

方法

完全を期すために、ツリー全体を構築し、システムをフラッシュするか、結果からOTAを適用することができます。

3
satur9nine
  <application
        Android:name=".xyzApp"
        Android:allowBackup="true"
    Android:persistent="false">

AndriodManifest.xmlでpersistent = "false"を作成します

0
Amruth A

この問題の回避策が見つかりました。新しいバージョンでプロセス名が変更された場合、更新は成功します

0
user3118604

簡単なハックと登録を使用して、デバイスにインストールされているすべてのアプリケーションの「Android.intent.action.PACKAGE_ADDED」インテントを受け取ることができます。追加されたアプリケーションにパッケージID(アプリが更新されたことを示す)がある場合は、強制的に終了させ、「永続化」メカニズムが新しいプロセスとして再起動するのを待つことができます。

私は複数のプラットフォームで永続的なアプリケーションを使用しており、あなたが説明しているような動作を見たことがないことに注意してください(使用しているプラ​​ットフォームを提供できれば役立つかもしれません)。

0
David Lev