web-dev-qa-db-ja.com

BroadcastReceiverをいつ登録解除しますか? onPause()、onDestroy()、またはonStop()で?

UnregisterReceiverはいつ使用する必要がありますか? onPause()onDestroy()、またはonStop()

注:サービスをバックグラウンドで実行する必要があります。

更新:

  1. レシーバーnullを解放する例外が発生します。

  2. unregisterReceiver();への呼び出しが欠落しているため、アクティビティがインテントレシーバーをリークしました

何か問題がある場合は教えてください、ここに私のコードがあります:

private boolean processedObstacleReceiverStarted;
private boolean mainNotificationReceiverStarted;

protected void onResume() {

    super.onResume();
    try {
        registerReceivers();

    } catch (Exception e) {

        Log.e(MatabbatManager.TAG,
                "MAINActivity: could not register receiver for Matanbbat Action "
                        + e.getMessage());
    }
}

private void registerReceivers() {

    if (!mainNotificationReceiverStarted) {
        mainNotificationReceiver = new MainNotificationReceiver();

        IntentFilter notificationIntent = new IntentFilter();

        notificationIntent
                .addAction(MatabbatManager.MATABAT_LOCATION_ACTION);
        notificationIntent
                .addAction(MatabbatManager.MATABAT_New_DATA_RECEIVED);
        notificationIntent
                .addAction(MatabbatManager.STATUS_NOTIFCATION_ACTION);
        registerReceiver(mainNotificationReceiver, notificationIntent);

        mainNotificationReceiverStarted = true;

    }

    if (!processedObstacleReceiverStarted) {
        processedObstacleReceiver = new ProcessedObstacleReceiver();
        registerReceiver(processedObstacleReceiver, new IntentFilter(
                MatabbatManager.MATABAT_ALARM_LOCATION_ACTION));
        processedObstacleReceiverStarted = true;

    }

}

private void unRegisterReceivers() {

    if (mainNotificationReceiverStarted) {
        unregisterReceiver(mainNotificationReceiver);
        mainNotificationReceiverStarted = false;
    }
    if (processedObstacleReceiverStarted) {
        unregisterReceiver(processedObstacleReceiver);
        processedObstacleReceiverStarted = false;
    }

}


@Override
protected void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();

    try {

        unRegisterReceivers();
        mWakeLock.release();//keep screen on
    } catch (Exception e) {
        Log.e(MatabbatManager.TAG, getClass() + " Releasing receivers-" + e.getMessage());
    }

}
30
Muhammad

受信者を登録した場所によって異なります。補完的なメソッドのペアは

onCreate - onDestroy
onResume - onPause
onStart  - onStop

最初のレシーバーで登録した場合は、終了メソッドでレシーバーの登録を解除します。

78
stinepike

Androidドキュメント から:

OnStop()を実装して、ネットワーク接続などのアクティビティリソースを解放するか、ブロードキャストレシーバーの登録を解除する必要があります。

次に、これらのペアに従います(@StinePikeのアナロジーを使用)。

onResume - onPause
onStart  - onStop

Androidライフサイクル のため、@ w3bsharkが言及したように:

HoneyComb以降(3.0以降)のデバイスでは、onStop()が最後に保証されたハンドラーです。

9
Evin1_

アクティビティが表示されていなくてもイベントをリッスンする場合は、onStop()でunregisterを呼び出します(たとえば、アクティビティAからアクティビティBを開きますが、Aにイベントをリッスンさせたい場合) 。

ただし、アクティビティが表示されているときにイベントのみをリッスンする場合は、onPauseでunregister()を呼び出します(たとえば、アクティビティAからアクティビティBを開きましたが、アクティビティAのイベントをリッスンしたくない場合)。

これがあなたの問題に役立つことを願っています。

1
Sudhanshu Gaur

放送受信機は目に見えないコンポーネントです。それは、onReceive()コールバックを介して何らかの変更に応答します。

したがって、アクティビティを応答する状態にあるとき、またはonResume()が呼び出されたときにEnabled/activeになったときにのみ、それらをアクティブにすることが理にかなっています。

したがって、onResume()-アクティビティが表示されて有効になっている場合は登録し、アクティビティがアクティブでなくなった場合はonStop()で登録を解除することをお勧めします。

1
WonderBoy