0

I have an issue with the navigation in my app. I have two activities, MainActivity and FormActivity. The main activity has a drawer layout, depending on the item selected it loads a fragment:

private void selectItem (int position) {
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager
            .beginTransaction();

    Fragment fragment = null;
    previousNavigationItem = position;

    switch (position)
    {
        case DASHBOARD_FRAGMENT:
            fragment = new DashboardFragment();
            mTitle = getResources().getString(R.string.title_dashboard);
            break;
        case LIST1_FRAGMENT:
            fragment = new ListFragment();
            mTitle = getResources().getString(R.string.title_list1);
            break;

        case LIST2_FRAGMENT:
            fragment = new ListFragment();
            mTitle = getResources().getString(R.string.title_list2);
            break;

        default:
            Log.w(AppController.ERROR_TAG, "Index out of bounds in changeFragment");
    }

    if (fragmentTransaction != null && fragment!=null) {
        fragment.setRetainInstance(true);
        fragmentTransaction.replace(R.id.content_frame, fragment);
        fragmentTransaction.addToBackStack(null);
        fragmentTransaction.commit();
    }
}

ListFragment loads a listview with some rows, when one item is selected it starts a new FormActivity:

protected void startForm(FormActivity.FORM_ACTION action, String dataClass, int groupPosition, long groupId) {
    Intent data = new Intent(getActivity(), FormActivity.class);
    data.setAction(action.toString());
    data.putExtra(FormActivity.BUNDLE_KEY_GROUP_POSITION, groupPosition);
    data.putExtra(FormActivity.BUNDLE_KEY_FORM_CLASS, dataClass);
    data.putExtra(FormActivity.BUNDLE_KEY_GROUP_ID, groupId);
    startActivityForResult(data, FormActivity.FORM_REQUEST_CODE);
}

in FormActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_form);

    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager
            .beginTransaction();

    Fragment fragment = null;
    try {
        (...I do some casting here but nothing to do with the problem..)
        fragment = new FormFragment();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

    if (fragmentTransaction != null && fragment!=null)
        fragmentTransaction.replace(R.id.form_frame, fragment).commit();

}

Everything works as expected except when i navigate back using the HomeUp button, MainActivity is destroyed then recreated again, and the savedInstance is not retained.

I have read all the documentation from Android Developers but still i did not find the culprit.

Edit:

In MainActivity

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    Log.d(AppController.DEBUG_TAG, "MainActivity onRestoreInstanceState");
    super.onRestoreInstanceState(savedInstanceState);
    // Restore the previously serialized current dropdown position.
    if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
        getSupportActionBar().setSelectedNavigationItem( savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
    }

}

@Override
public void onSaveInstanceState(Bundle outState) {
    Log.d(AppController.DEBUG_TAG, "MainActivity onSaveInstanceState");
    super.onSaveInstanceState(outState);
    // Serialize the current dropdown position.
    outState.putInt(STATE_SELECTED_NAVIGATION_ITEM,
            getSupportActionBar().getSelectedNavigationIndex());
    Log.d(AppController.DEBUG_TAG, "Selected item id in Navigation Drawer: " + mDrawerList.getSelectedItemId());
}
spacebiker
  • 3,777
  • 4
  • 30
  • 49

1 Answers1

1

See this:

http://developer.android.com/guide/topics/manifest/activity-element.html#lmode

Basically there can be multiple activities of the same kind going on at any given time.

Also understand that onDestroy can be called at any time based on system resources and it's best to prepare for this gracefully.

EDIT:

Ok I appear to have mis-understood something.

You're going to have to use SharedPreferences or some other method of persistance for this. If android is completely closing out your application then your savedInstance bundle's resources are likely being released.

Shared preferences is a very standard way of doing persistance and works very well...

See:

http://developer.android.com/guide/topics/data/data-storage.html#pref

Nathaniel D. Waggoner
  • 2,856
  • 2
  • 19
  • 41
  • I already read those documents, but the question is, how can i keep the previous state from bundle if the bundle gets recreated too? I have edited my question adding the (previously in my code) onRestoreInstanceState and onSaveInstanceState overrides. – spacebiker Dec 16 '13 at 22:11
  • Are you sure? I don't see the onSaveInstanceState here. – Nathaniel D. Waggoner Dec 16 '13 at 22:13
  • just added after writing the comment, it should be there now if you refresh – spacebiker Dec 16 '13 at 22:13
  • take a close look at: http://developer.android.com/reference/android/app/Activity.html And look very closely at the lifecycle diagram... – Nathaniel D. Waggoner Dec 16 '13 at 22:24
  • I read somewhere that i could solve it by storing the values in SharedPreferences, but i'd like to keep the application as much standard as possible, and i think the "SharedPreference" method is some kind of "patch". – spacebiker Dec 16 '13 at 22:25
  • 1
    Sorry i misunderstood this early on. Yes you'll need to sue sharedPreferences. This is VERY standard and well supported, and will work across force closes, phone being turned off/on etc... – Nathaniel D. Waggoner Dec 16 '13 at 22:29