Android 何时注销广播接收器?在onPause()、onDestroy()或onStop()中?

Android 何时注销广播接收器?在onPause()、onDestroy()或onStop()中?,android,broadcastreceiver,intentservice,Android,Broadcastreceiver,Intentservice,我应该什么时候使用unregisterReceiver?在onPause()、onDestroy()或onStop()中 注意:我需要在后台运行该服务 更新: 我得到一个异常null 活动已泄漏您是否缺少对unregisterReceiver()的调用 如果有什么问题,请告诉我,这是我的代码: private boolean processedObstacleReceiverStarted; private boolean mainNotificationReceiverStarted; pr

我应该什么时候使用unregisterReceiver?在
onPause()
onDestroy()
onStop()

注意:我需要在后台运行该服务

更新:

  • 我得到一个异常
    null

  • 活动已泄漏您是否缺少对
    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());
        }
    
    }
    

    这取决于你在哪里注册了接收器。互补方法对为

    onCreate - onDestroy
    onResume - onPause
    onStart  - onStop
    

    如果在第一个接收器中注册,则在其结束方法中取消注册。

    广播接收器是不可见的组件。它所做的一切都是通过onReceive()回调响应某种更改

    因此,只有当您的活动处于要响应的状态或处于启用/活动状态时(即调用onResume()时),才有必要激活它们

    因此,更好的做法是在onResume()中注册-当活动可见并启用时,以及在onStop()中注销活动不再活动时。

    来自:

    您应该实现onStop()来释放活动资源,例如 网络连接或取消注册广播接收器

    然后,我将遵循这些配对(使用@StinePike的类比):

    因为,正如@w3bshark所提到的:

    在后蜂窝(3.0+)设备中,onStop()是最后保证的处理程序


    就这么简单,如果您想在活动不可见的情况下监听事件,那么在onStop()中调用unregister (例如,从活动A打开活动B,但如果您希望A仍在侦听事件)

    但当您只想在活动可见时侦听事件时,请在onPause call unregister()中 (例如,在活动A中,您打开了活动B,但现在您不想侦听活动A中的事件)


    希望这有助于解决您的问题。

    首先,您不必调用生命周期方法,如onPause()、onDestroy()或onStop()。您的应用程序的预期行为是什么?上面提到的所有情况都是有效的,这取决于您的使用情况这里有一个明确的答案:Help answer@nAkhmedov,请您解释一下,在应用程序终止之前(如果您支持预蜂窝设备),保证调用的最后一个生命周期事件处理程序处于暂停状态。如果您只支持后蜂窝设备,那么onStop是最后保证的处理程序。您永远不应该假设onDestroy将被调用,因此,您应该在此生命周期事件之前注销接收器。来源:@w3bshark:如果您的进程被终止以回收内存,那么您是否注销接收器并不重要,因为您的应用程序将从内存(包括接收器)中退出。如果你有持久性的东西,你只需要担心可终止状态,你必须保证方法会被调用。这通常不起作用,因为活动B的onStart/onResume发生在活动A之上之前(从A->B移动时)。错误的活动可能会捕获您的广播,导致调试困难。因此,您必须在onResume和onPause中注册和注销接收器,因为在片段或活动被销毁之前,它们将被确定调用。当我们将活动A调用为活动B时,活动A进入ON STOP状态,接收器将被取消注册,并且不会收听广播。
    onResume - onPause
    onStart  - onStop