简体   繁体   中英

Android onRestoreInstanceState not updating fully on orientation change

I have a problem in a counting program that shows how many times a method such as onCreate, onStart etc. was called and it seems to be working fine when I go from Activity1 to Activity2 and then back to Activity1 but when I switch orientation, only mResume gets increased. So for example when I start the app and switch orientation 3 times the result looks like this:

onCreate() calls:1  
onStart() calls:1  
onResume() calls:4  
onRestart() calls:1

Another wierd thing is that when I commented out mResume,mRestart and mStart from onRestoreInstanceState, then suddenly 2 variables get updated mStart and mResume.

public void onRestoreInstanceState(Bundle savedInstanceState) {
    // Always call the superclass so it can restore the view hierarchy
    super.onRestoreInstanceState(savedInstanceState);

    Log.i(TAG, "Entered the onRestoreInstanceState() method");

    // Restore state members from saved instance
    //mResume = savedInstanceState.getInt(RESUME_KEY);
    //mRestart = savedInstanceState.getInt(RESTART_KEY);
    //mStart = savedInstanceState.getInt(START_KEY);
    mCreate = savedInstanceState.getInt(CREATE_KEY);

here is the full code

public class ActivityOne extends Activity {    
    // Use these as keys when you're saving state between reconfigurations
    private static final String RESTART_KEY = "restart";
    private static final String RESUME_KEY = "resume";
    private static final String START_KEY = "start";
    private static final String CREATE_KEY = "create";

    // String for LogCat documentation
    private final static String TAG = "Lab-ActivityOne";

    // Lifecycle counters

    // TODO:
    // Create variables named
    // mCreate, mRestart, mStart and mResume
    // to count calls to onCreate(), onRestart(), onStart() and
    // onResume(). These variables should not be defined as static.

    // You will need to increment these variables' values when their
    // corresponding lifecycle methods get called.
    int mCreate;
    int mRestart;
    int mStart;
    int mResume;

    // TODO: Create variables for each of the TextViews
    // named mTvCreate, mTvRestart, mTvStart, mTvResume.
    // for displaying the current count of each counter variable

    TextView mTvCreate;
    TextView mTvRestart;
    TextView mTvResume;
    TextView mTvStart;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_one);

        // TODO: Assign the appropriate TextViews to the TextView variables
        // Hint: Access the TextView by calling Activity's findViewById()
        // textView1 = (TextView) findViewById(R.id.textView1);
        mTvCreate = (TextView) findViewById(R.id.create);
        mTvRestart = (TextView) findViewById(R.id.restart);
        mTvStart = (TextView) findViewById(R.id.start);
        mTvResume = (TextView) findViewById(R.id.resume);

        Button launchActivityTwoButton = (Button) findViewById(R.id.bLaunchActivityTwo);
        launchActivityTwoButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO:
                // Launch Activity Two
                // Hint: use Context's startActivity() method

                // Create an intent stating which Activity you would like to
                // start
                Intent intent = new Intent(v.getContext(), ActivityTwo.class);

                // Launch the Activity using the intent
                startActivity(intent);

            }
        });

        // Has previous state been saved?
        if (savedInstanceState != null) {

            // TODO:
            // Restore value of counters from saved state
            // Only need 4 lines of code, one for every count variable
            mCreate = savedInstanceState.getInt(CREATE_KEY);
            mRestart = savedInstanceState.getInt(RESTART_KEY);
            mStart = savedInstanceState.getInt(START_KEY);
            mResume = savedInstanceState.getInt(RESUME_KEY);

        }

        // Emit LogCat message
        Log.i(TAG, "Entered the onCreate() method");

        // TODO:
        // Update the appropriate count variable
        // Update the user interface via the displayCounts() method
        mCreate += 1;
        displayCounts();

    }

    // Lifecycle callback overrides

    @Override
    public void onStart() {
        super.onStart();

        // Emit LogCat message
        Log.i(TAG, "Entered the onStart() method");

        // TODO:
        // Update the appropriate count variable
        // Update the user interface
        mStart += 1;
        displayCounts();

    }

    @Override
    public void onResume() {
        super.onResume();

        // Emit LogCat message
        Log.i(TAG, "Entered the onResume() method");

        // TODO:
        // Update the appropriate count variable
        // Update the user interface
        mResume += 1;
        displayCounts();

    }

    @Override
    public void onPause() {
        super.onPause();

        // Emit LogCat message
        Log.i(TAG, "Entered the onPause() method");
    }

    @Override
    public void onStop() {
        super.onStop();

        // Emit LogCat message
        Log.i(TAG, "Entered the onStop() method");
    }

    @Override
    public void onRestart() {
        super.onRestart();

        // Emit LogCat message
        Log.i(TAG, "Entered the onRestart() method");

        // TODO:
        // Update the appropriate count variable
        // Update the user interface
        mRestart += 1;
        displayCounts();

    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        // Emit LogCat message
        Log.i(TAG, "Entered the onDestroy() method");
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);

        Log.i(TAG, "Entered the onSaveInstanceState() method");
        // TODO:
        // Save state information with a collection of key-value pairs
        // 4 lines of code, one for every count variable
        savedInstanceState.putInt(CREATE_KEY, mCreate);
        savedInstanceState.putInt(RESTART_KEY, mRestart);
        savedInstanceState.putInt(START_KEY, mStart);
        savedInstanceState.putInt(RESUME_KEY, mResume);


    }

    public void onRestoreInstanceState(Bundle savedInstanceState) {
        // Always call the superclass so it can restore the view hierarchy
        super.onRestoreInstanceState(savedInstanceState);

        Log.i(TAG, "Entered the onRestoreInstanceState() method");

        // Restore state members from saved instance
        mResume = savedInstanceState.getInt(RESUME_KEY);
        mRestart = savedInstanceState.getInt(RESTART_KEY);
        mStart = savedInstanceState.getInt(START_KEY);
        mCreate = savedInstanceState.getInt(CREATE_KEY);

        //displayCounts();
    }

    // Updates the displayed counters
    // This method expects that the counters and TextView variables use the
    // names
    // specified above
    public void displayCounts() {

        mTvCreate.setText("onCreate() calls: " + mCreate);
        mTvStart.setText("onStart() calls: " + mStart);
        mTvResume.setText("onResume() calls: " + mResume);
        mTvRestart.setText("onRestart() calls: " + mRestart);

    }
}

here is the xml

<LinearLayout   xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView android:id="@+id/create"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/onCreate" />

    <TextView android:id="@+id/start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/onStart" />

    <TextView android:id="@+id/resume"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/onResume" />

    <TextView android:id="@+id/restart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/onRestart" />

    <Button android:id="@+id/bLaunchActivityTwo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button" />

</LinearLayout>

You are getting the values of mCreate , mStart , mRestart and mResume from the Bundle object twice, in onCreate and in onRestoreInstanceState . This means that any changes to your counts made between retrieving the values the two times will be ignored.

If it is called at all, onRestoreInstanceState gets called after onCreate , so you should not restore the values in onRestoreInstanceState as they would already have been restored in onCreate .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM