我正在使用 Otto 事件总线订阅 ListFragment 中的某些事件。总线实例是在 Application 的子类中存储和创建的,换句话说,它的总线应该作为单例工作。好像不是这样的……
fragment 在 onActivityCreated(Bundle)
中注册到总线,在 onDestroy()
中注销。这不起作用。当调用 unregister()
(java.lang.IllegalArgumentException:缺少注释方法的事件处理程序...)时,我从设备上收到了应用程序崩溃的几份崩溃报告。只有在对 register() 的任何调用之前调用了 unregister()
,或者如果调用了两次 unregister()
,才会抛出此异常。这可能只发生在......
onActivityCreated(Bundle)
未在onDestroy()
之前调用。onDestroy()
被调用了两次。Application
实例在调用onActivityCreated(Bundle)
和onDestroy()
之间重新创建。
我的应用类:
public class App extends Application {
private static App sInstance;
private Bus bus;
public static App getInstance() {
return sInstance;
}
@Override
public void onCreate() {
super.onCreate();
sInstance = this;
bus = new Bus(ThreadEnforcer.ANY);
}
public Bus getEventBus() {
return bus;
}
}
fragment 类:
public class MyFragment extends ListFragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
App.getInstance().getEventBus().register(this);
}
@Subscribe
public void onEvent(MyEvent event) {
....
}
@Override
public void onDestroy() {
App.getInstance().getEventBus().unregister(this);
super.onDestroy();
}
}
更新:
我漏掉了一个重要的细节;这些 fragment 用于 ViewPager
。当用户在 ViewPager
中的页面之间滑动时,它们会按需实例化。这个小细节似乎改变了某些设备上的 fragment 生命周期:onActivityCreated()
永远不会为在 ViewPager
创建后启动的 fragment 调用。
最佳答案
我有同样的问题。在某些情况下,实例会在总线上保持注册状态。一个可靠的解决方案是使用 onStart()
/onStop()
方法来注册/注销接收器。这也是 Square 家伙的建议。他们是这样解释的。如果 Activity 在后台,则无论如何都不需要刷新 UI,因为 UI 是不可见的。一旦 Activity 出现在前台,它将接收更新并刷新 UI。
更新:如评论中所述,在 onResume()
/onPause()
中注册/注销可能会在某些情况下导致一些不良影响如果在您的 Activity 上显示一个对话框,Activity 就会暂停并且无法再接收事件。
关于android - fragment 实例中带有 Otto 事件总线的 IllegalArgumentException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19692711/