什么是更有效的广播接收器或处理程序?

时间:2014-08-11 14:52:25

标签: android multithreading broadcastreceiver handler

我知道广播接收器的onReceive()和Handler的handleMessage()在同一个UI线程上运行。假设我想在同一个app(进程)中的两个服务之间进行通信。我可以扩展广播接收器类并注册事件

OR

一个Handler,然后将其实例传递给另一个用于sendMessage()调用的服务。在这两种情况下,我都需要添加一些新的开关案例。但哪种方法更有效?让我们假设代码是线程安全的(没有UI更新)。

3 个答案:

答案 0 :(得分:26)

您不应该使用普通广播在自己应用内的ActivitiesServices之间进行通信。你应该使用本地广播!首先,您必须为普通广播定义BroadcastReceiver

private static final String ACTION_EXAMPLE = "ACTION_EXAMPLE";

private final BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(ACTION_EXAMPLE.equals(intent.getAction())) {
            ...
        }  
    }
};

之后你就可以得到这样的LocalBroadcastManager

LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity());

您可以像这样注册BroadcastReceiver(通常在BroadcastReciever注册onResume()):

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

    LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity());
    IntentFilter filter = new IntentFilter(ACTION_EXAMPLE);
    manager.registerReceiver(this.receiver, filter);
}

请勿忘记稍后取消注册BroadcastReceiveronPause()中):

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

    LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity());
    manager.unregisterReceiver(this.receiver);
}

最后你可以发送这样的本地广播:

LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity());
manager.sendBroadcast(intent);

答案 1 :(得分:23)

  

我可以扩展广播接收器类并注册事件

如果您的意思是通过LocalBroadcastManager执行此操作(请参阅Mr. Kapeller's excellent answer for details),Handler会稍微提高效率,因为LocalBroadcastManager使用Handler 。但是,性能差异不应该足够重要。其他进行中的事件总线实现也是如此,例如greenrobot的EventBus和Square的Otto。所有这些都应该足够快,以至于其他问题,例如可维护性,应该是最重要的。

如果您的意思是通过系统广播(例如,在sendBroadcast()上调用Context),那么HandlerLocalBroadcastManager或其他事件总线实现将会更快,更安全。

所有这些都假设这两个服务处于同一个过程中。

最快的解决方案是将两种服务合二为一。如果它们具有相同的寿命,则尤其如此。在很多情况下,应用程序中有2个以上的服务是合理的,但是如果没有明确的理由,不要创建大量独立的小服务。

答案 2 :(得分:2)

广播接收器呼叫是繁重的操作,如果事件被多次广播,则有机会获得ANR。而且,在获得应用程序上下文之前,你在广播接收器的onReceive()中获得的上下文使用有限。

相比之下,处理程序调用很有效,因为它们很简单并且在不同的线程中运行,并且不需要上下文来启动处理程序调用。可以使用处理程序轻松处理2个服务或活动之间的通信或2个线程。事实上所有其他方式即... Intents和Bound服务在内部使用处理程序来传递消息。