Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

savedInstanceState is always null, yet onSaveInstanceState() is always called

First of all I'm new to Android - this question could seem stupid :)

I've created an main Activity that contains a ViewPager. The ViewPager is linked to my ActionBar tabs. Currently my main Activity contains 3 tabs in this way.

My issue is the following: when I'm on the 3rd tab and create a new Activity and afterwards return to my main Activity I always return to my 1st tab.

I've tried the following approach in my main Activity:

// debugger breakpoints tell me this method is always called when other activity is shown ...
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    int pos = getActionBar().getSelectedNavigationIndex();
    outState.putInt("tab", pos);
}

// however, in onCreate() my savedInstanceState is always 'null' ...
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    this.invalidateOptionsMenu();

    setContentView(R.layout.activity_main);

    final ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    mSectionsPagerAdapter = new SectionsPagerAdapter(
            getSupportFragmentManager());

    mViewPager = (ViewPager) findViewById(R.id.pager);
    mViewPager.setAdapter(mSectionsPagerAdapter);

    mViewPager
            .setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
                @Override
                public void onPageSelected(int position) {
                    actionBar.setSelectedNavigationItem(position);
                }
            });

    for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
        actionBar.addTab(actionBar.newTab()
                .setText(mSectionsPagerAdapter.getPageTitle(i))
                .setTabListener(this));
    }

    // trying to restore state here, yet savedInstanceState is _always_ null ...
    if (savedInstanceState != null) {
        actionBar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
    }
}

I've read that the savedInstanceState will always be null when there's no id defined. My XML layout has an id defined though, so this should not be an issue. I've also read that the 'onSaveInstanceState()` method should always call the method on the super class first, so I've implemented the method accordingly.

Anyone have any idea how to fix my issue? How to get the ViewPager to show the right tab / fragment when the main Activity is recreated?

like image 317
Wolfgang Schreurs Avatar asked Jan 30 '13 00:01

Wolfgang Schreurs


People also ask

Is onSaveInstanceState always called?

I'm aware that onSaveInstanceState() is not always called when an activity is about to be destroyed. For example, if it is destroyed because the user has pressed the "back" button, the activity state is not preserved.

What is the significance of onSaveInstanceState () and onRestoreInstanceState ()?

The onSaveInstanceState() method allows you to add key/value pairs to the outState of the app. Then the onRestoreInstanceState() method will allow you to retrieve the value and set it back to the variable from which it was originally collected.

Why is savedInstanceState null?

The logs always show the "bundle save" tag. But in onCreate method, SavedInstanceState is always null. you need to call super. onSaveInstanceState(savedInstanceState) before adding your values to the Bundle, or they will get wiped out on that call (Droid X Android 2.2).

What is savedInstanceState in Java?

The savedInstanceState is a reference to a Bundle object that is passed into the onCreate method of every Android Activity. Activities have the ability, under special circumstances, to restore themselves to a previous state using the data stored in this bundle.


2 Answers

Thanks She Smile, your suggestions helped me solve my issue, because it helped me find the source of my problem.

Apparently onCreate() could only have a savedInstanceState parameter when the Activity was completely destroyed and recreated. In my case the Activity still existed though, therefore I will not have a savedInstanceState parameter. My "fix" was to create a static int that contains the selected tab index. I realise this might not be the best solution, since this variable will be shared across all instances of the Activity, but since in my situation there will only even be one instance of my activity it should be fine.

public class MainActivity extends Activity implements ActionBar.TabListener {
    private static int tabIdx;

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

        if (savedInstanceState != null) {
            tabIdx = savedInstanceState.getInt("tab", 0);
        }
        getActionBar().setSelectedNavigationItem(tabIdx);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        tabIdx = getActionBar().getSelectedNavigationIndex();
        outState.putInt("tab", tabIdx);
    }
}
like image 61
Wolfgang Schreurs Avatar answered Nov 16 '22 01:11

Wolfgang Schreurs


so if the onSaveInstance was Called

you can declare a global variable for your

 int pos=0; 

after onSaveInstance() gets called, method below is called:

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
pos=savedInstanceState.getInt("tab", 0);    

}

so in your onCreate() function replace the condition from this:

if (savedInstanceState != null) {
    actionBar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0));
}

to this:

if(pos>0){
actionBar.setSelectedNavigationItem(pos);
}
like image 21
She Smile GM Avatar answered Nov 16 '22 01:11

She Smile GM