15

I have an activity, its layout contains a FrameLayout. I use the framelayout as a fragment container. I replace the fragments in the FrameLayout using FragmentManager transactions.

In one of the fragment's onCreate method I register the fragment with the EventBus using.

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

The fragment has a GridView in its layout. Whenever an item in the gridView is clicked I post an event to the 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());
        }
    });

The event handler methods for this event are in the same fragment i.e. The fragment has the following method

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

This works fine until the app loses focus and becomes inactive (due to pressing the home button or screen lock). When I make the app active again, the event handlers for the events are not called. I can see the following statements in the 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

Can someone tell me what am I doing wrong here?

Edit 1:

When the application becomes inactive due to screen lock or the home button being pressed, the fragment's onStop method is called. The code to unregister the fragment from the EventBus is in the onStop method. When application becomes active again, the fragment's onStart and onResume methods are called. So I moved my code to register the fragment with the EventBus in its onStart method.

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

I put some log statements to check if the onStart method is actually called when the application become active. It is being called. Still things are not working when the application becomes inactive and then active again.

Edit 2 I forgot to mention that the activity which contains this fragment also subscribes to EventBus. The code to register the activity with the EventBus is in its onCreate method and the code to unregister the activity is in its onStop method.

GunnerFan
  • 3,576
  • 3
  • 25
  • 38

2 Answers2

9

The activity which contained this fragment also subscribed to EventBus. The code to register the activity with the EventBus was in its onCreate method and the code to unregister the activity was in its onStop method.

When the application was becoming inactive (due to screen lock or pressing the Home Button) the containing activity's onStop method was being called and it was getting unregisterd from the EventBus. For some reason its containing fragments were also getting unregistered (I am not sure why). Re-registering the fragments with the EventBus did not work.

I solved this problem by moving the code to unregister the containing activity to its onDestroy method.

I am still not sure why doing this works, but atleast it solves my current problem. If someone has an explanation or better insight please comment or post an answer.

GunnerFan
  • 3,576
  • 3
  • 25
  • 38
  • 2
    If I understand correctly, the lifecycle will not call onCreate again unless the Fragment is destroyed which will not necessarily the case in every instant. So onStop gets called but unless onDestroy gets call onCreate will not. I would expect onStart (not sure with Fragments) but not onCreate. – Alex Beggs Dec 05 '14 at 04:52
0

For me the problem was something else, I tried to do a post to a fragment that was not yet committed. You will receive the same 2 errors as stated in the question.

So I did a getSupportFragmentManager().executePendingTransactions(); before calling the post and that fixed the problem for me.

Edward van Raak
  • 4,841
  • 3
  • 24
  • 38