android - fragment 实例中带有 Otto 事件总线的 IllegalArgumentException

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

我正在使用 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/

相关文章:

android - 如何在单击按钮时显示/隐藏 fragment

android - 当另一个 fragment 位于顶部时,主机 fragment 接收触摸事件

android - 我的应用不适用于 Google Play 上的平板设备

android - 按钮在设备中不可见

java - 通过 Android 应用程序在网络服务器上上传多个文件

android - 子 Activity 的生命周期

java - 无法构建插件flutter_plugin_android_lifecycle

Android - Samsung Galaxy S4 重启问题

android - fragment 中的抽屉导航后退按钮

Android - 返回登录屏幕时清除内存中的现有对象和变量