2

IntentFilter と BroadcastReceiver を持つ Activity があり、それらを my に登録しますonCreate()

IntentFilter filter = new IntentFilter(ACTION_RCV_MESSAGE);
filter.addCategory(Intent.CATEGORY_DEFAULT);
receiver = new MessageReceiver();
registerReceiver(receiver, filter);

しかし、アプリを終了すると、Logcat は次のように言います。

07-03 01:38:19.567: ERROR/ActivityThread(304): android.app.IntentReceiverLeaked: アクティビティ com.intentservicetest5.IntentServiceTest5Activity は、もともとここに登録されていた IntentReceiver com.intentservicetest5.IntentServiceTest5Activity$MessageReceiver@44efe8a8 を漏らしました。unregisterReceiver() への呼び出しがありませんか?

しかし、私は持っています

public void onDestroy(Bundle savedInstanceState){
    unregisterReceiver(receiver);
}

を呼び出したときにアクティビティがまだリークしているのはなぜunregisterReceiver()ですか?

4

4 に答える 4

5

Activity Lifecycleに従って、アプリはonPause()ほとんどのデバイス (Android 3.0 / API レベル 12 未満のデバイス) でいつでも強制終了でき、その後はどのデバイスでもいつでも強制終了onStop()できます。つまりonDestroy()、呼び出される保証はありません。アクティビティ内でブロードキャストを登録および登録解除するのに最適な場所は、それぞれonResume()およびです。onPause()

@Override
protected void onResume() {
    super.onResume();

    IntentFilter filter = new IntentFilter(ACTION_RCV_MESSAGE);
    filter.addCategory(Intent.CATEGORY_DEFAULT);
    receiver = new MessageReceiver();
    registerReceiver(receiver, filter);
}

@Override
protected void onPause() {
    super.onPause();

    unregisterReceiver(receiver);
}

@VipalShah が指摘したように、 に間違った署名を使用していたことに注意してくださいonDestroy()。これがunregisterReceiver()呼ばれなかった理由です。を使用@Overrideすると、この種の問題をキャッチするのに役立ちます。

onPause()また、との間の対称性onResume()は意図的なものであることに注意してください。上記にリンクされているアクティビティのライフサイクルの記事を見るとonResume()、一時停止から再開するときだけでなく、最初の起動時に呼び出されることがわかります。したがって、 ではなく、ここでブロードキャストに登録するだけで済みますonCreate()

最後に、簡単にするためにコードを使用したことに注意してください。onCreate()実際には、IntentFilter と MessageReceiver を に設定してから、 を呼び出すだけでよいregisterReceiver()でしょうonResume()

更新:もう 1 つ重要な注意事項があります。ライフサイクルコールバックの実装に従って:

これらのライフサイクル メソッドの実装では、作業を行う前に常にスーパークラスの実装を呼び出す必要があります。

ここにいる多くの人super.onWhatever()は、メソッドの最初ではなく、最後に への呼び出しを示していました。

于 2012-07-03T04:51:00.747 に答える
1

onDestroyは、アプリケーションの終了時に常に呼び出されるとは限りません。onStopまたはonPause の登録を解除してみてください。

また、オーバーライドされたメソッドでアクティビティのスーパー クラス メソッドを呼び出すようにしてください。

@Override
public void onPause() {
    unregisterReceiver(receiver);
    super.onPause();
}
于 2012-07-03T04:29:42.857 に答える
0
    @Override
        protected void onPause() {
            super.onPause();
            unregisterReceiver(receiver);
        }   

試してみてくださいonPause()

于 2012-07-03T04:29:35.257 に答える
0

この onDestroy() を使用してみてください

@Override
protected void onDestroy() {

    unregisterReceiver(receiver);

    super.onDestroy();
}
于 2012-07-03T04:43:12.950 に答える