web-dev-qa-db-ja.com

アクティビティで作成されたブロードキャストレシーバーをいつ登録/登録解除しますか?

アクティビティのonCreateイベントでカスタムブロードキャストレシーバーを作成する必要があり、明らかにアクティビティのonDestroyイベントでブロードキャストレシーバーの登録を解除する必要があります

明確にするために、これは私が使用するコードのスニペットです

public class AnActivity extends Activity {
    private ResponseReceiver receiver;

    public class ResponseReceiver extends BroadcastReceiver {
           public static final String ACTION_RESP =
              "mypackagename.intent.action.MESSAGE_PROCESSED";

           @Override
            public void onReceive(Context context, Intent intent) {
// TODO Start a dialogue if message indicates successfully posted to server
            }
    }   

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        IntentFilter filter = new IntentFilter(ResponseReceiver.ACTION_RESP);
        filter.addCategory(Intent.CATEGORY_DEFAULT);
        receiver = new ResponseReceiver();
        registerReceiver(receiver, filter);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }

アクティビティのonPause/onResumeおよびonStart/onStopイベントもブロードキャストレシーバーを登録および登録解除する必要があることを読みました。

このためのベストプラクティスと考えられるものとその理由を本当に理解したいと思っています。

73
jamesc

レシーバーonStart()およびonStop()を登録および登録解除する必要があります。

アクティビティがBroadcastReceiversを登録する唯一の理由は、現在のアクティビティで何らかの方法でイベントを使用し、ユーザーにイベントを通知するためです。 onStop()が呼び出されている場合、Activityはフォアグラウンドにないため、ユーザーを更新できません。

バックグラウンドでブロードキャストイベントを受信する場合は、 here のようにサービスの使用を検討する必要があります。

Konstantinが言うように、onDestroy()の呼び出しは保証されていません。また、Activityが開いていない場合は、長時間ブロードキャストを受信し続けることができます。

84
SnowyTracks

onDestroy()の呼び出しが保証されていないため、onPause()を使用して登録解除する必要があります。ブロードキャストレシーバーのライフサイクルを検討します。アクティビティがフォアグラウンドにある場合にのみ、アクティブにする必要がありますか?次にonResume()/onPause()を使用します

19

Androidドキュメンテーションは、放送受信機を登録/登録解除する単一の場所を規定していませんが、 言及している both onStart()/onStop()onResume()/onPause()可能性として。

この決定をする最大の要因は、受信者がいつその仕事をする必要があるかです。これにより、いつ登録および登録解除するかが決まります。

  • 受信者は、アクティビティに焦点が合っている場合にのみ、ブロードキャストについて何かをする必要がありますか?その場合は、onPause()/onReceive()で登録/登録解除できます。 (onStart()/onStop()などの長いライフタイムを使用することもできますが、レシーバーのonReceive()の間にアクティビティがフォーカスされているかどうかを確認する必要があります。)

  • 受信者は、フォーカスがなくても(ダイアログが表示されているときなど)、表示されているときに何かをする必要がありますか?その場合は、onStart()/onStop()を使用します(または、より長いライフタイムですが、受信者のonReceive()はアクティビティが表示されるかどうかを確認する必要があります)。

  • アクティビティが表示されない場合でも、受信者はブロードキャストについて知る必要がありますか?たとえば、何かが起こったことを覚えておく必要があるので、アクティビティが見えるようになると、結果の状態を反映できますか?次に、onCreate()/onDestroy()を使用して登録/登録解除する必要があります。 (この種の機能を実装する他の方法があることに注意してください。)

onStart()に登録する場合は、onResume()にも登録しないでください。これは冗長になるためです。onResume()は、onStart()が最初に呼び出されない限り呼び出されません。

また、 onPause()を可能な限り軽くする :が最善であることにも留意してください。

onPause()の実行は非常に短時間であり、必ずしも保存操作を実行するのに十分な時間があるわけではありません。このため、onPause()を使用して、アプリケーションまたはユーザーデータを保存したり、ネットワーク呼び出しを行ったり、データベーストランザクションを実行したりしないでください。そのような作業は、メソッドが完了する前に完了しない場合があります。代わりに、onStop()中に高負荷シャットダウン操作を実行する必要があります。

システムがメモリを節約するためにプロセスを強制終了した場合、onDestroy()呼び出されることが保証されない であることは事実です。ただし、プロセスが強制終了された場合、プロセスはブロードキャストを受信しません。その場合、放送受信機の登録を解除する必要は本当にありますか?

8
LarsH

Androidは、onStop()メソッドを省略してアプリケーションを強制終了できます。この状況を解決する最良の方法は、onResume()メソッドでBroadcastReceiverを登録し、onPause()で登録解除することです。

5
ukson

OnResume()およびonPause()メソッドでブロードキャストを登録および登録解除する必要があります。

onStart()で登録し、onStop()で登録解除した場合。そのとき、次の問題が発生します。

デバイスの画面がロックされている場合、onStop()が呼び出され、ロック解除されている場合、onStart()は呼び出されません。これが、onResume()およびonPause()メソッドで登録および登録解除した理由です。

0