How to save an activity state using save instance

2020-01-22 11:01发布

I've been working on the Android SDK platform, and it is a little unclear how to save an application's state. So given this minor re-tooling of the 'Hello, Android' example:

package com.android.hello;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class HelloAndroid extends Activity {

  private TextView mTextView = null;

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mTextView = new TextView(this);

    if (savedInstanceState == null) {
       mTextView.setText("Welcome to HelloAndroid!");
    } else {
       mTextView.setText("Welcome back.");
    }

    setContentView(mTextView);
  }
}

I thought it would be enough for the simplest case, but it always responds with the first message, no matter how I navigate away from the app.

I'm sure the solution is as simple as overriding onPause or something like that, but I've been poking away in the documentation for 30 minutes or so and haven't found anything obvious.

30条回答
冷血范
2楼-- · 2020-01-22 11:14

There are basically two ways to implement this change.

  1. using onSaveInstanceState() and onRestoreInstanceState().
  2. In manifest android:configChanges="orientation|screenSize".

I really do not recommend to use second method. Since in one of my experience it was causing half of the device screen black while rotating from portrait to landscape and vice versa.

Using first method mentioned above , we can persist data when orientation is changed or any config change happens. I know a way in which you can store any type of data inside savedInstance state object.

Example: Consider a case if you want to persist Json object. create a model class with getters and setters .

class MyModel extends Serializable{
JSONObject obj;

setJsonObject(JsonObject obj)
{
this.obj=obj;
}

JSONObject getJsonObject()
return this.obj;
} 
}

Now in your activity in onCreate and onSaveInstanceState method do the following. It will look something like this:

@override
onCreate(Bundle savedInstaceState){
MyModel data= (MyModel)savedInstaceState.getSerializable("yourkey")
JSONObject obj=data.getJsonObject();
//Here you have retained JSONObject and can use.
}


@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Obj is some json object 
MyModel dataToSave= new MyModel();
dataToSave.setJsonObject(obj);
oustate.putSerializable("yourkey",dataToSave); 

}
查看更多
来,给爷笑一个
3楼-- · 2020-01-22 11:14

There is a way to make Android save the states without implementing any method. Just add this line to your Manifest in Activity declaration:

android:configChanges="orientation|screenSize"

It should look like this:

<activity
    android:name=".activities.MyActivity"
    android:configChanges="orientation|screenSize">
</activity>

Here you can find more information about this property.

It's recommended to let Android handle this for you than the manually handling.

查看更多
该账号已被封号
4楼-- · 2020-01-22 11:16

onSaveInstanceState is called when the system needs memory and kills an application. It is not called when the user just closes the application. So I think application state should also be saved in onPause It should be saved to some persistent storage like Preferences or Sqlite

查看更多
放荡不羁爱自由
5楼-- · 2020-01-22 11:16

Instead of that, you should use ViewModel, which will retain the data until the activity life cycle.

查看更多
Emotional °昔
6楼-- · 2020-01-22 11:17

When an activity is created it's onCreate() method is called.

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

savedInstanceState is an object of Bundle class which is null for the first time, but it contains values when it is recreated. To save Activity's state you have to override onSaveInstanceState().

   @Override
    protected void onSaveInstanceState(Bundle outState) {
      outState.putString("key","Welcome Back")
        super.onSaveInstanceState(outState);       //save state
    }

put your values in "outState" Bundle object like outState.putString("key","Welcome Back") and save by calling super. When activity will be destroyed it's state get saved in Bundle object and can be restored after recreation in onCreate() or onRestoreInstanceState(). Bundle received in onCreate() and onRestoreInstanceState() are same.

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

          //restore activity's state
         if(savedInstanceState!=null){
          String reStoredString=savedInstanceState.getString("key");
            }
    }

or

  //restores activity's saved state
 @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
      String restoredMessage=savedInstanceState.getString("key");
    }
查看更多
仙女界的扛把子
7楼-- · 2020-01-22 11:18

To get activity state data stored in onCreate(), first you have to save data in savedInstanceState by overriding SaveInstanceState(Bundle savedInstanceState) method.

When activity destroy SaveInstanceState(Bundle savedInstanceState) method gets called and there you save data you want to save. And you get same in onCreate() when activity restart.(savedInstanceState wont be null since you have saved some data in it before activity get destroyed)

查看更多
登录 后发表回答