Fragment实例中带有Otto事件总线的IllegalArgumentException

时间:2013-10-30 19:59:35

标签: android android-fragments activity-lifecycle otto fragment-lifecycle

我正在使用Otto Event总线订阅ListFragment中的某些事件。总线实例在Application的子类中存储和创建,换句话说,它应该作为单例工作。看来这不是一个案例......

片段正在onActivityCreated(Bundle)注册到总线,并在onDestroy()中取消注册。这不起作用。我从调用unregister()时应用程序崩溃的设备获得了几个崩溃报告(java.lang.IllegalArgumentException:带注释方法的缺少事件处理程序......)。如果在调用register()之前调用unregister(),或者调用unregister()两次,则仅抛出此异常。这可能只发生在......

    {li> 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();
    }
}

更新:

我遗漏了一个重要的细节;这些片段用于ViewPager。当用户在ViewPager中的页面之间滑动时,它们会根据需要进行实例化。这个小细节似乎改变了某些设备上的片段生命周期:onActivityCreated()永远不会在创建ViewPager后启动的片段中调用。

1 个答案:

答案 0 :(得分:36)

我有同样的问题。在某些情况下,实例仍在公交车上登记。一个可靠的解决方案是使用onStart() / onStop()方法注册/取消注册接收器。这也是Square家伙的建议。他们这样解释。如果活动在后台,则无论如何都不需要刷新UI,因为UI不可见。一旦活动出现在前台,它将接收更新和刷新UI。

更新,如评论中所述,在onResume() / onPause()中注册/取消注册可能会在某些情况下导致一些不良影响,例如,如果您的对话框中显示了对话框活动,然后活动暂停,无法再接收活动。