EP21 Activity在非正常行为下的数据保存和恢复

Activity在非正常行为下的数据保存和恢复

onSaveInstanceState

今天同举在移植CPActivity到印尼钱包的时候遇到了一个数据保存的问题,这里简单了解了一下。

比如我们要做一个游戏软件,如果 Activity 当前被停止长期未使用(比如用户离开了),或者游戏被压到后台了,前台Activity需要更多资源以致系统必须关闭后台进程恢复内存,Activity也可能被系统销毁。在这种「非正常应用行为」结束的情况下,已经被销毁的Activity实例在用户重新打开Activity的时候会被恢复。

有一个回调方法叫作 onSaveInstanceState(),Activity开始停止时系统会调用它。如果你使用这个回调方法然后什么都不做的话,那么系统会在Bundle里为你保存Activity布局。比如你已经在EditText里输入了文字了,Activity恢复的时候这些文字也会恢复。如果你想保存其他东西,也可以往Bundle里添加:

static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
//...

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

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

然后在恢复的时候,可以选择两种方式:

  1. onCreate()
  2. onRestoreInstanceState()

使用onCreate()的话,需要判断savedInstanceState是否为空,比如对于上面的游戏的例子,恢复用户的得分和等级:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); // Always call the superclass first

    // Check whether we're recreating a previously destroyed instance
    if (savedInstanceState != null) {
        // Restore value of members from saved state
        mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
        mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
    } else {
        // Probably initialize members with default values for a new instance
    }
    //...
}
复制代码

更具体的,在JDRActivity里,我们看到如果传进来的bundle为空,就初始化uidata,否则就获取保存在bundle中的uidata:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState == null) {
            mUIData = initUIData();
        } else {
            savedInstanceState.setClassLoader(getClass().getClassLoader());
            mUIData = (UIData) savedInstanceState.getSerializable(UIDATA);
            postRestoreUIData(savedInstanceState);
        }

//更多操作...
//...
    }

复制代码

也可以使用 onRestoreInstanceState()这个回调方法,这个方法在onStart之后,onCreate之前。这种情况下不需要判断savedInstanceState是否为空,因为只有不为空的时候系统才会调用这个。

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);
    mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
复制代码

persistAcrossReboots

有一个有趣的新特性,可以实现关机后数据保存。在API 21之后,如果在Manifest中加入:

android:persistableMode="persistAcrossReboots"
复制代码

现在,下面三个方法中中,都添加了这样的一个新的Bundle:

public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState)

public void onRestoreInstanceState(Bundle savedInstanceState, PersistableBundle persistentState)

public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState)
复制代码

这个Bundle用来保存关机后的数据(我猜的,没有验证过)。

Reference:
[1]https://developer.android.com/training/basics/activity-lifecycle/recreating.html
[2]https://developer.android.com/guide/components/activities.html
[3]http://blog.csdn.net/lincyang/article/details/45287599

转载于:https://juejin.im/post/5a3131596fb9a044fa19dcca

你可能感兴趣的:(EP21 Activity在非正常行为下的数据保存和恢复)