IllegalArgumentException with Otto Event bus in Fragment instance

给你一囗甜甜゛ 提交于 2019-12-18 10:55:18

问题


I am using Otto Event bus to subscribe to certain events in a ListFragment. The bus instance is stored and created in an subclass of Application, in other words, it bus should work as a singleton. It seems like this is not a case...

The fragment is registering to the bus in onActivityCreated(Bundle) and unregistering in onDestroy(). This does not work as it should. I have gotten several crash reports from devices where the app crashes when calling unregister() (java.lang.IllegalArgumentException: Missing event handler for an annotated method...). This exception is only thrown if unregister() is called before any call to register(), or if unregister() is called twice. This may only happen if...

  • onActivityCreated(Bundle) is not called before onDestroy().
  • onDestroy() is called twice.
  • The Application instance is recreated between between the call to onActivityCreated(Bundle) and onDestroy().

My application class:

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;
    }

}

The Fragment class:

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

UPDATE:

I left out an important detail; the fragments were used in a ViewPager. They are instantiated on demand as the users slides between the pages in the ViewPager. This minor detail seems alter the fragments life-cycle on some devices: onActivityCreated() is never called for fragments initiated after the ViewPager is created.


回答1:


I had same issue. Instance stayed registered in the bus in some cases. A reliable solution is to use onStart()/onStop() methods to register/unregister receivers. This is what Square guys suggest too. They explain it like this. If activity is in background, it does not need to refresh UI anyway, because UI is not visible. Once activity comes foreground, it will receive update and refresh UI.

Update: as mentioned in the comments, registering / unregistering in onResume()/onPause() can cause some undesired effects in certain cases like if there is a dialog shown over your activity, then activity gets paused and is not able to receive events anymore.



来源:https://stackoverflow.com/questions/19692711/illegalargumentexception-with-otto-event-bus-in-fragment-instance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!