现在,Activity可以使用以下三种方式之一连接到服务:
我认为BroadcastReceivers是最简单的通信方式,但我在想为什么要使用其他方式?换句话说,何时使用messengers或AIDL将比broadcastreceivers更好?
我通常倾向于使用LocalBroadcasts
。它们就像真正的广播一样,但仅对您的应用程序可见。首先,您必须像处理正常广播一样创建一个BroadcastReceiver
:
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(Intent.SOME_ACTION.equals(action)) {
// Do your work
}
}
};
@Override
public void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter(Intent.SOME_ACTION);
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity());
manager.registerReceiver(broadcastReceiver, intentFilter);
}
@Override
public void onPause() {
super.onPause();
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity());
manager.unregisterReceiver(broadcastReceiver);
}
最后,您可以从Service
或应用程序中的任何其他位置发送广播,如下所示:
Intent intent = new Intent(Intent.SOME_ACTION);
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity());
manager.sendBroadcast(intent);
BroadcastReceiver
来实现Service
和Activity
之间的通信。
Messenger
和AIDL
主要用于应用程序需要与其他进程(IPC)进行通信的情况。在这种情况下,您的接口应该具有一个定义了响应不同类型的Message
对象的Handler
的Service
。Messenger
和AIDL
之间的区别非常简单。当您使用Messenger
时,它会将所有请求排队到一个单独的线程中。因此,您的Service
不必是线程安全的。如果您希望Service
同时处理多个请求,则可以直接使用AIDL
。在这种情况下,您的Service
必须具备多线程能力并构建为线程安全。实际上,Messenger
是在AIDL
之上实现的。Xaver Kapeller的答案确实很好。然而,它有一个(主要)缺点:广播可能会被错过。
当用户离开Activity
(例如显示最近的应用程序)时,您需要注销您的BroadcastReceiver
。如果在那个时候发送广播,则您的Activity
将无法接收到它。当返回到Activity
时,它可能处于无效状态。
使用ResultReceiver
,您仍然可以在这种情况下接收结果。此外,ResultReceiver
是可parcelable
的,因此您可以在生命周期事件中保存和恢复它。
但是,这会导致一些额外的开销,这就是为什么我创建了这个实验性库来简化它。目前它只使用IntentService
,但应该很容易扩展。