我已经为我的应用程序实现了一条总线,用于片段和活动之间的通信。我通过向列表中添加Fragment
或Activity
的实例来添加订阅者。我通过调用一个方法来迭代该列表,以通知每个订阅者正在发生的事情。现在我需要保持列表的整洁,我不想在列表中添加同一类的多个实例。我可以将equals()
用于Activity
,但不能用于Fragment
,因为它是最终的,所以我不能覆盖它。
我尝试了什么
我已经尝试在列表中保留每个订阅者的Class
对象,该对象在我调用该方法之前运行良好。如果没有可从中调用的实例,就无法调用方法。所以这是行不通的。
我还可以保留一个单独的列表,一个用于存放Class
对象,另一个用于保存实际实例。但如果可能的话,我希望避免添加另一个依赖项。
我也可以手动对每个Fragment
进行instanceof
检查,但我不想这样做,因为我已经有5个片段了,如果我添加或删除任何片段,那么我必须回到这里更新这个方法。
因此,我的问题是,除了添加另一个List
来保存Class
对象或手动检查instanceof
之外,还有其他方法可以确保我不会向订阅者List
添加多个实例吗?
如果你需要,这里有相关的代码:
public void subscribe(Object object) {
if (!mSubscribers.contains(object)) {
mSubscribers.add(object);
}
}
public void notifySubscribers(BusEvent event) throws InvocationTargetException, IllegalAccessException {
for (Object o : mSubscribers) {
Method methodToCall = getMethodToCall(o);
if (methodToCall != null) {
methodToCall.invoke(o, event);
}
}
}
好的,我找到了一个合适的答案来解决我的问题。我想在这里分享它,希望它能帮助其他人。Android有一个名为LocalBroadcastManager
的类。它在v4支持库中可用。在您的活动中,您调用"LocalBroadcastManager.getInstance().registerReceiver()"。您向该方法传递一个扩展BroadcastReceiver
的类和一个"IntentFilter"来告诉接收器要侦听什么。然后,在包括Fragment
s在内的任何类中,调用LocalBroadcastManager.getInstance().sendBroadcast()
并传入与注册时使用的IntentFilter
匹配的Intent
。这是我用来让它工作的代码:
private void registerLocalBroadcastReceiver() {
// call this method in your activity (or any class you want to listen for broadcasts)
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this);
manager.registerReceiver(new OpenMenuBroadcastReceiver(), new IntentFilter("open-html"));
}
private void sendMessageToActivity(int position) {
// use this in a fragment (or any other class) to send a message
LocalBroadcastManager broadcast = LocalBroadcastManager.getInstance(getActivity());
Intent message = new Intent("open-html");
String name = (String) getListAdapter().getItem(position);
message.putExtra("name", name);
broadcast.sendBroadcast(message);
}
class OpenMenuBroadcastReceiver extends BroadcastReceiver {
// this is an inner class to my activity, when you send the message this method
// will be called to handle the message
@Override
public void onReceive(Context context, Intent intent) {
String name = intent.getStringExtra("name");
if (name != null && name.equalsIgnoreCase("home")) {
replaceFragment(Tag.HOME_FRAGMENT.getTag(), new HomeFragment(), R.id.main_frame);
mDrawerLayout.closeDrawer(Gravity.START);
return;
}
openMenuItemsFragment(name);
}
}
这方面的好处是,它完全是你的应用程序的本地版本。外部应用程序无法接收您的广播,因此它是安全的。你可以在安卓开发者网站上找到更多关于如何使用它的信息。