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

bjo*_*ncs 13 android activity-lifecycle android-fragments otto fragment-lifecycle

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

该片段正在注册到总线onActivityCreated(Bundle)并取消注册onDestroy().这不起作用.我从调用应用程序崩溃的设备获得了几个崩溃报告unregister()(java.lang.IllegalArgumentException:缺少注释方法的事件处理程序......).如果unregister()在调用register()之前调用,或者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;
    }

}
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:

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

ser*_*nka 36

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

更新:如评论中所述,在某些情况下注册/取消注册onResume()/ onPause()可能会导致某些不良影响,例如,如果您的活动上显示对话框,则活动会暂停,并且无法再接收事件.

  • 除了特殊目的之外,不要在各自的```onResume()```/```onPause()````````````````/```unregister()```Otto分段.我发现了一个漏洞.如果在应该接收总线事件的片段上显示一个对话框,片段上的```onPause()``将被调用并意外取消注册Otto. (7认同)
  • @ThuyTrinh这不是明确的'onPause`的目的吗? (5认同)
  • 问题是:如果片段正在等待后台任务,那么会发生什么,从服务器获取项目列表.如果用户在绘制列表之前离开片段,您将永远不会获得项目,因为片段已取消注册总线,对吧? (2认同)