Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Losing data when rotate screen

I have a little funny bug in my application. When the user rotates the screen I lose some of the data in my activity. Anyone that have an idea of why this happens?

like image 788
Roland Avatar asked Feb 25 '11 22:02

Roland


People also ask

Why an activity is destroyed and recreated when you rotate your screen?

Background. When you rotate your device and the screen changes orientation, Android usually destroys your application's existing Activities and Fragments and recreates them. Android does this so that your application can reload resources based on the new configuration.

How do I stop Android from restarting activity when changing orientations?

If you want the activity to not restart during screen orientation change, you can use the below AndroidManifest. xml. Please note the activity android:configChanges=”orientation|screenSize” attribute. This attribute makes the activity not restart when change screen orientation.


3 Answers

//Use onSaveInstanceState(Bundle) and onRestoreInstanceState

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {

  // Save UI state changes to the savedInstanceState.   
  // This bundle will be passed to onCreate if the process is  
  // killed and restarted.

  savedInstanceState.putBoolean("MyBoolean", true);  
  savedInstanceState.putDouble("myDouble", 1.9);  
  savedInstanceState.putInt("MyInt", 1);  
  savedInstanceState.putString("MyString", "Welcome back to Android");  

  // etc.  

  super.onSaveInstanceState(savedInstanceState);  
}  

//onRestoreInstanceState  

@Override  
public void onRestoreInstanceState(Bundle savedInstanceState) {  

  super.onRestoreInstanceState(savedInstanceState);  

  // Restore UI state from the savedInstanceState.  
  // This bundle has also been passed to onCreate.  

  boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");  
  double myDouble = savedInstanceState.getDouble("myDouble");  
  int myInt = savedInstanceState.getInt("MyInt");  
  String myString = savedInstanceState.getString("MyString");  
}

This is how you save your data when the system deletes it on rotation.

like image 92
jaisonDavis Avatar answered Oct 14 '22 13:10

jaisonDavis


By default, when the screen is rotated your Activity is killed and restarted. To make sure no data is lost, you need to properly save and restore your data using the lifecycle methods. See Saving Persistent State.

like image 24
Cheryl Simon Avatar answered Oct 14 '22 14:10

Cheryl Simon


More Detail

People have already provided the code. So I am going to add more details on that.

What happens when screen rotates?

When the screen rotates the configuration of the Activity changes so System looks for a more suitable resource for the Activity. For this purpose System kills the instance of the activity and recreates a new instance of the Activity.

How does System creates a new Instance?

System tries to recreate the instance using a set of saved data of old Activity instance known as instance state. InstanceState is a collection of Key-Value Pair stored in a Bundle object.

System saved some data automatically

By default System saves the View objects in the Bundle for example.

  • Text in EditText
  • Scroll position in a ListView etc

If you want to store more data which should survive orientation change. You should override onSaveInstanceState(Bundle savedInstanceState) method.

Use onSaveInstaneState correctly

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current game state
    savedInstanceState.putInt(STATE_SCORE, mCurrentScore);

    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(savedInstanceState);
}

So by mistake if you forget to call super.onSaveInstanceState(savedInstanceState) the default behavior will not work ie Text in EditText will not save. If you don't believe me check this out

Which method to use to restore state ?

Many people get confused including me. Should I choose

  • onCreate(Bundle savedInstanceState)

OR

  • onRestoreInstanceState(Bundle savedInstanceState)

It does not matter. Both methods receive the same bundle in the parameter. The only difference is that you need to provide a null check in onCreate(Bundle savedInstanceState) method. But if you are going to use onRestoreInstanceState(Bundle savedInstanceState), use it carefully

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

    // Restore state members from saved instance
    mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
}

Always call super.onRestoreInstanceState(savedInstanceState) so that System restore the View hierarchy by default

like image 28
Rohit Singh Avatar answered Oct 14 '22 15:10

Rohit Singh