11

Application クラスから派生したクラスを持つアプリケーションがあり、その onCreate() メソッドが複数回呼び出されていることに気付きました。これに加えて、静的変数の値は onCreate() が呼び出されるたびにリセットされます。

この動作は M でのみ発生し、L では発生しません。M のバグなのか、M の意図的な変更なのか、アプリのアーキテクチャに根本的な固有の問題があるのか​​ を調べようとしています。 Mで顕在化。

Application 派生クラスの onCreate() は、ブロードキャスト レシーバの onReceive() が呼び出されるたびに呼び出されます。Application クラスの複数のインスタンスが作成されていない - onCreate() が同じオブジェクト インスタンスで呼び出されており、同じアプリケーション コンテキストが全体に存在します。

この観察結果を示すいくつかのコード スニペットを次に示します。

public class MyApplication extends Application
{
    public static int debugVal = 5;

    public MyApplication ()
    {
        theApp = this;
    }

    public void onCreate ()
    {
        Log.v(TAG, "++++++++++++ onCreate() debugVal: " + debugVal);
        debugVal = 10;
        ....



public class MyBroadcastReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive (Context context, Intent intent)
    {
    Log.v(TAG, "onReceive. debugVal: " + MyApplication.debugVal);
    ...

Marshmallow で実行すると、logcat の出力は次のようになります。

831-1412/? I/ActivityManager Start proc 2244:com.company.redacted/u0a86 for broadcast com.company.redacted/com.company.redacted2.MyBroadcastReceiver
2244-2244/? V/MyApplication: ++++++++++ onCreate() debugVal: 5
2244-2244/? V/MyBroadcastReceiver: onReceive. debugVal: 10
...
831-1327/? I/ActivityManager: Start proc 3271.com.company.redacted/u0a86 for broadcast com.company.redacted2/com.company.redacted1.MyBroadcastReceiver
3271-3271/? V/MyApplication: +++++++++++ onCreate() debugVal: 5
....

onCreate() が複数回呼び出される様子と、2 回目に onCreate() が呼び出されるまでに debugVal が値 10 を失っている様子を確認してください。同じ .apk が Lollipop で実行される場合、onCreate() への 2 番目の呼び出しは存在しません。

L のログは次のようになります。

768-783/? I/ActivityManager: Start proc 2480:com.company.redacted/u0a84 for broadcast com/company.redacted1/com.company.redacted2/MyBroadcastReceiver
2480-2480/? V/MyApplication: +++++++++++ onCreate() debugVal:5
2480-2480/? V/MyBroadcastReceiver: onReceive. debugVal: 10
....
2480-2480/com.company.redaced1 v/MyBroadcastReceiver: onReceive. debugVal: 10

何が起こっているのかを知り、それを排除したいのですが、それができない場合は、Application クラスを、静的変数が安全で信頼性が高く、一度だけ初期化されることが保証されているシングルトン クラスに置き換えることは可能でしょうか?

これは、起動時に開始されるプリインストールされたアプリ (受信者がリッスンするインテントの 1 つ) であり、この時点では Actives はありません。

4

3 に答える 3

3

同じプロセスで onCreate() が 2 回呼び出されていると言いますが、それはおそらく正しくありません。マシュマロがプロセスの強制終了に積極的である可能性は非常に高いです。これは、使用可能なメモリが少ないか、アイドル状態のパッケージの強制終了に積極的であるためです ( 「空の #17」については、この問題とCACHED_EMPTY に言及しているドキュメントを参照してください)。

確認するには、永続的な通知でstartForegroundを呼び出して、サービスをフォアグラウンド サービスにします。問題が解決した場合は、OS がプロセスを強制終了したことを意味します。

一般に、バックグラウンドで実行し続けることに依存するべきではありません。初期化をできるだけ怠惰できめ細かくし、ブロードキャスト レシーバーなどのバックグラウンド操作をできるだけ安価にします。

于 2015-10-25T21:45:59.113 に答える
0

静的変数は状態を保持するのに適していません。この理由は、静的変数がライフサイクルとアプリの起動/シャットダウン全体で存続しないためです。通常、定数状態には静的変数のみを使用します。これは、同じ初期値を持つ変数または定数である変数を意味します。

値が変更されている場合は、Prefs などのストレージに保存する必要があります。


OnCreate を複数回呼び出す理由については、実装している BroadcastReceiver の種類について詳しく教えてください。

着信インテントが構成変更を引き起こし、アプリケーションを破棄して再作成する可能性があります。

于 2015-10-30T05:29:40.390 に答える