15

我有一个活动,它的布局包含一个 FrameLayout。我使用框架布局作为片段容器。我使用 FragmentManager 事务替换 FrameLayout 中的片段。

在片段的 onCreate 方法之一中,我使用 EventBus 注册片段。

@Override
public void onCreate(){
  EventBus.getDefault().register(this);
  // other initialization code
}

该片段的布局中有一个 GridView。每当单击 gridView 中的项目时,我都会将事件发布到 EventBus

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState){
    View rootView = inflater.inflate(R.layout.fragment_category, container, false);
    gridView = (GridView) rootView.findViewById(R.id.categry_grid_view);
    gridAdapter = new CustomGridAdapter(getActivity());
    gridView.setAdapter(gridAdapter);

    gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
            Category clickedCategory = gridAdapter.getItem(position);
            EventBus.getDefault().post(new MyEvent());
        }
    });

此事件的事件处理程序方法在同一个片段中,即片段具有以下方法

public void onEvent(MyEvent e){
    //some code;
}

这工作正常,直到应用程序失去焦点并变为非活动状态(由于按下主页按钮或屏幕锁定)。当我再次激活应用程序时,不会调用事件的事件处理程序。我可以在 LogCat 中看到以下语句

com.example.app D/Event﹕ No subscribers registered for event class com.example.app.MyEvent
com.example.app D/Event﹕ No subscribers registered for event class de.greenrobot.event.NoSubscriberEvent

有人可以告诉我我在这里做错了什么吗?

编辑1:

当应用程序由于屏幕锁定或按下主页按钮而变为非活动状态时,将调用片段的 onStop 方法。从 EventBus 中注销片段的代码在 onStop 方法中。当应用程序再次激活时,将调用片段的 onStart 和 onResume 方法。所以我移动了我的代码,在其 onStart 方法中使用 EventBus 注册片段。

@Override
public void onStart(){
  super.onStart();
  EventBus.getDefault().register(this);
}

我放了一些日志语句来检查应用程序激活时是否实际调用了 onStart 方法。它正在被调用。当应用程序变为非活动状态然后再次活动时,仍然无法正常工作。

编辑 2 我忘了提到包含这个片段的活动也订阅了 EventBus。向 EventBus 注册活动的代码在其 onCreate 方法中,取消注册活动的代码在其 onStop 方法中。

4

2 回答 2

9

包含此片段的活动也订阅了 EventBus。向 EventBus 注册活动的代码在其 onCreate 方法中,而取消注册活动的代码在其 onStop 方法中。

当应用程序变为非活动状态时(由于屏幕锁定或按下 Home 按钮),正在调用包含活动的 onStop 方法,并且它正在从 EventBus 中注销。由于某种原因,它包含的片段也被取消注册(我不知道为什么)。使用 EventBus 重新注册片段不起作用。

我通过将代码取消注册包含活动到其 onDestroy 方法解决了这个问题。

我仍然不确定为什么这样做有效,但至少它解决了我当前的问题。如果有人有解释或更好的见解,请发表评论或发布答案。

于 2014-10-07T08:24:42.267 回答
0

对我来说,问题是别的,我试图在尚未提交的片段上发帖。您将收到与问题中所述相同的 2 个错误。

所以我getSupportFragmentManager().executePendingTransactions();在打电话之前做了一个帖子,这为我解决了这个问题。

于 2016-03-28T20:52:20.963 回答