Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sometimes Fragment not attached to Activity (onCreateOptionsMenu)

Not sure why, but I get a few error-reports from an app in the playstore which have the message:

java.lang.IllegalStateException: Fragment NewsOverViewFragment{4062e840} not attached to Activity
   at android.support.v4.app.Fragment.getResources(Fragment.java:601)
   at de.dala.simplenews.ui.NewsOverViewFragment.shouldUseMultipleColumns(NewsOverViewFragment.java:153)
   at de.dala.simplenews.ui.NewsOverViewFragment.updateMenu(NewsOverViewFragment.java:145)
   at de.dala.simplenews.ui.NewsOverViewFragment.onCreateOptionsMenu(NewsOverViewFragment.java:139)

I already did a fix and check whether the fragment is attached to the activity but this is just "avoiding" the problem. In my opinion it should never occure to get a notattached-state in onCreateOptionsMenu or onOptionsItemSelected.

Why would this occure? How is it possible for the fragment to call onCreateOptionsMenu/onOptionsItemSelected without being attached to the activity?

Regards

Code:

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    menu.clear();
    inflater.inflate(R.menu.news_overview_menu, menu);
    updateMenu();
    super.onCreateOptionsMenu(menu, inflater);
}

private void updateMenu(){
    boolean useMultiple = shouldUseMultipleColumns();
    ...
}

private boolean shouldUseMultipleColumns(){
    boolean useMultiple = false;

    Configuration config = getActivity().getResources().getConfiguration();
            switch (config.orientation) {
                case android.content.res.Configuration.ORIENTATION_LANDSCAPE:
                    useMultiple = PrefUtilities.getInstance().useMultipleColumnsLandscape();
                    break;
                case android.content.res.Configuration.ORIENTATION_PORTRAIT:
                    useMultiple = PrefUtilities.getInstance().useMultipleColumnsPortrait();
                    break;
      }

    return useMultiple;
}

Like I said I now check whether the fragment is attached and only then call shouldUseMultipleColumns() which fixes the problem but does not explain why this is called in the first place...

Edit2: My Activity

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ...
    if (savedInstanceState == null) {
        if (getIntent().getDataString() != null) {
            String path = getIntent().getDataString();
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            currentFragment = CategoryModifierFragment.getInstance(path);
            transaction.replace(R.id.container, currentFragment).commit();
        } else {
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            currentFragment = NewsOverViewFragment.getInstance(NewsOverViewFragment.ALL);
            transaction.replace(R.id.container, currentFragment).commit();
        }
    }
    ...
}

This is basically the attaching procedure. However, it is possible to call other fragments which are always replacing the currentFragment so there is a chance that my NewsOverViewFragment is NOT attached. But even if this is the case - why is onCreateOptionsMenu called?

like image 743
Frame91 Avatar asked Aug 30 '14 13:08

Frame91


People also ask

Can we use fragments without activity?

It can't exist independently. We can't create multi-screen UI without using fragment in an activity, After using multiple fragments in a single activity, we can create a multi-screen UI. Fragment cannot be used without an Activity.

How do I attach a fragment to an activity?

Add a fragment to an activity You can add your fragment to the activity's view hierarchy either by defining the fragment in your activity's layout file or by defining a fragment container in your activity's layout file and then programmatically adding the fragment from within your activity.

Are fragments destroyed when activity is destroyed?

As Fragment is embedded inside an Activity, it will be killed when Activity is killed. As contents of activity are first killed, fragment will be destroyed just before activity gets destroyed.


1 Answers

you should check the isAdded() function of fragment http://developer.android.com/reference/android/app/Fragment.html#isAdded()

so your shouldUseMultipleColumns() will look like that

private boolean shouldUseMultipleColumns(){
    if(!isAdded()) return false;
    boolean useMultiple = false;

    Configuration config = getActivity().getResources().getConfiguration();
            switch (config.orientation) {
                case android.content.res.Configuration.ORIENTATION_LANDSCAPE:
                    useMultiple = PrefUtilities.getInstance().useMultipleColumnsLandscape();
                    break;
                case android.content.res.Configuration.ORIENTATION_PORTRAIT:
                    useMultiple = PrefUtilities.getInstance().useMultipleColumnsPortrait();
                    break;
      }

    return useMultiple;
}
like image 142
gmetax Avatar answered Oct 07 '22 19:10

gmetax