关于android:何时注册/取消注册活动中创建的广播接收器?

When to Register/Unregister Broadcast Receivers created in an activity?

我需要在活动的onCreate事件中创建自定义广播接收器,显然我需要在活动的onDestroy事件中取消注册广播接收器

为清楚起见,这是我使用的代码片段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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事件也应该注册和取消注册广播接收器。

我真的很想了解什么被认为是最好的做法和原因。


您应该注册和取消注册您的接收器onStart()onStop()

活动注册BroadcastReceiver的唯一原因是以某种方式对当前活动使用事件,以通知用户事件。如果已调用onStop(),则Activity不再位于前台,因此无法更新用户。

如果您想在后台接收广播事件,则应考虑使用此处所示的服务。

就像康斯坦丁所说的那样,onDestroy()不能保证被调用,当Activity不再打开时,你可以继续接收广播很长一段时间。


由于onDestroy()不能保证被调用,因此您应使用onPause()取消注册。考虑广播接收器的生命周期:只有当您的活动在前台时,您是否需要它才能激活?然后使用onResume() / onPause()


Android文档没有规定注册/取消注册广播接收器的单个位置,但它提到了onStart() / onStop()onResume() / onPause()两种可能性。

做出此决定的最大因素是,您的接收器何时需要能够完成其工作?这将决定何时注册和注销它。

  • 仅当活动处于焦点时,接收者是否需要对广播做些什么?如果是这样,您可以在onPause() / onReceive()中注册/取消注册。 (您也可以使用更长的生命周期,例如onStart() / onStop(),但是您应该在接收者的onReceive()期间检查活动是否处于焦点。)

  • 接收器是否需要在可见时执行某些操作,即使它没有焦点(例如,当显示对话框时)?如果是这样,请使用onStart() / onStop()(或更长的生命周期,但同样,接收方的onReceive()应检查活动是否可见)。

  • 即使活动不可见,接收者是否需要知道广播?例如,它是否需要记住发生的事情,以便当活动变得可见时,它可以反映出事态的结果?然后,您需要使用onCreate() / onDestroy()注册/取消注册。 (注意还有其他方法可以实现这种功能。)

如果在onStart()中注册,请不要在onResume()中注册它们,因为这将是多余的:如果不首先调用onStart(),则永远不会调用onResume()

另请注意,最好将onPause()尽可能保持亮:

onPause() execution is very brief, and does not necessarily afford
enough time to perform save operations. For this reason, you should
not use onPause() to save application or user data, make network
calls, or execute database transactions; such work may not complete
before the method completes. Instead, you should perform heavy-load
shutdown operations during onStop().

确实,如果系统杀死您的进程以节省内存,则无法保证调用onDestroy()。但是,如果该进程被终止,则该进程无论如何都不会接收广播。在这种情况下,是否真的有必要取消注册广播接收器?


Android可以通过省略onStop()方法来终止您的应用程序。解决这种情况的最佳方法是在onResume()方法中注册BroadcastReceiver并在onPause()中取消注册。


您应该在onResume()和onPause()方法中注册和取消注册您的广播。

如果您在onStart()中注册并在onStop()中取消注册它。那个时候你会得到以下问题。

if your device screen is lock that time onStop() is called and if you unlock that time onStart() is never called. thats why you have register and unregister it in onResume() and onPause() methods.