savedInstanceState

1、protected void onCreate(@Nullable Bundle savedInstanceState)
这个savedInstanceState值什么时候会保存呢?系统异常退出时还是自己退出?需不需要手动保存

官方介绍:https://developer.android.com/training/basics/activity-lifecycle/recreating?hl=zh-cn
如果用户按了返回键或者说手动调用finish()销毁了Activity,这种情况我们不用管。
这些情况需要考虑(有些设备配置可能会在运行时发生变化):
https://developer.android.com/guide/topics/resources/runtime-changes?hl=zh-cn

  • 如果我们按了home键退到了后台或者说跳转到了其他Activity,这时候如果 Activity 长期未使用,或者前台 Activity 需要更多资源以致系统必须关闭后台进程恢复内存。
  • 旋转屏幕导致Activity重建

针对上述情况,默认情况下,系统会使用 Bundle实例状态保存您的 Activity 布局(比如,输入到 EditText对象中的文本值)中有关每个 View 对象的信息。 这样,如果您的 Activity 实例被销毁并重新创建,布局状态便恢复为其先前的状态,且您无需代码。 但是,您的 Activity 可能具有您要恢复的更多状态信息,比如跟踪用户在 Activity 中进度的成员变量。

要保存有关 Activity 状态的其他数据,您必须替代 onSaveInstanceState() 回调方法。当用户要离开 Activity 并在 Activity 意外销毁时向其传递将保存的 Bundle 对象时,系统会调用此方法。 如果系统必须稍后重新创建 Activity 实例,它会将相同的 Bundle 对象同时传递给 onRestoreInstanceState() 和 onCreate()方法。

image.png
保存 Activity 状态

当您的 Activity 开始停止时,系统会调用 onSaveInstanceState() 以便您的 Activity 可以保存带有键值对集合的状态信息。 此方法的默认实现保存有关 Activity 视图层次的状态信息,例如 EditText小部件中的文本或ListView 的滚动位置。

要保存 Activity 的更多状态信息,您必须实现 onSaveInstanceState()并将键值对添加至 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);
}
恢复 Activity 状态

在恢复数据时,有两个地方可以恢复,第一个是onCreate()方法,第二个是onRestoreInstanceState()方法,但是需要判断null

@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
    }
    ...
}

第二个就无需判断null

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);
}

如果重启 Activity 需要恢复大量数据,比如:重新建立网络连接或执行其他密集操作,那么因配置变更而引起的完全重启可能会给用户留下应用运行缓慢的体验

有些设备配置可能会在运行时发生变化(例如屏幕方向、键盘可用性及语言)。 发生这种变化时,Android 会重启正在运行的 Activity(先后调用 onDestroy() 和 onCreate(),重启行为旨在通过利用与新设备配置匹配的备用资源自动重新加载您的应用,来帮助它适应新配置。

此外,依靠系统通过onSaveInstanceState() 回调为您保存的 Bundle,可能无法完全恢复 Activity 状态,因为它并非设计用于携带大型对象(例如位图),而且其中的数据必须先序列化,再进行反序列化,这可能会消耗大量内存并使得配置变更速度缓慢。 在这种情况下,如果 Activity 因配置变更而重启,则可通过保留 Fragment 来减轻重新初始化 Activity 的负担。此片段可能包含对您要保留的有状态对象的引用。

package com.example.huozhenpeng.myapplication;

import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

/**
 * 作者 huozhenpeng
 * 日期 2018/7/11
 * 邮箱 huohacker@sina.com
 */

public class SecondActivity extends AppCompatActivity {

    private RetainedFragment dataFragment;

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

        // find the retained fragment on activity restarts
        FragmentManager fm = getSupportFragmentManager();

        dataFragment = (RetainedFragment) fm.findFragmentByTag("data");

        // create the fragment and data the first time
        if (dataFragment == null) {
            // add the fragment
            dataFragment = new RetainedFragment();
            fm.beginTransaction().add(dataFragment,"data").commit();
        }

        // the data is available in dataFragment.getData()
        //恢复复杂数据
        MyDataObject myDataObject=dataFragment.getData();
        if(myDataObject!=null)
        {
            Log.e("abc",myDataObject.getName());
        }

    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.e("abc","stop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e("abc","destroy");
        // store the data in the fragment
        //保存复杂数据
        dataFragment.setData(new MyDataObject("复杂数据"));
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.e("abc","onSaveInstanceState");
    }



    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.e("abc","onRestoreInstanceState");
    }
}

package com.example.huozhenpeng.myapplication;

import android.os.Bundle;
import android.support.v4.app.Fragment;

public class RetainedFragment extends Fragment {

    // data object we want to retain
    private MyDataObject data;

    // this method is only called once for this fragment
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // retain this fragment
        setRetainInstance(true);
    }

    public void setData(MyDataObject data) {
        this.data = data;
    }

    public MyDataObject getData() {
        return data;
    }
}
package com.example.huozhenpeng.myapplication;

/**
 * 作者 huozhenpeng
 * 日期 2018/7/11
 * 邮箱 huohacker@sina.com
 */

public class MyDataObject {

    public MyDataObject(String name)
    {
        this.name=name;
    }

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

注意:尽管您可以存储任何对象,但是切勿传递与 Activity 绑定的对象,例如,Drawable、Adapter、View或其他任何与 Context 关联的对象。否则,它将泄漏原始 Activity 实例的所有视图和资源。 (泄漏资源意味着应用将继续持有这些资源,但是无法对其进行垃圾回收,因此可能会丢失大量内存。)

当然,你也可以阻止Activity重启,请在清单文件中编辑相应的 <activity>元素,以包含 android:configChanges属性以及代表要处理的配置的值。android:configChanges属性的文档中列出了该属性的可能值(最常用的值包括 "orientation""keyboardHidden",分别用于避免因屏幕方向和可用键盘改变而导致重启)。您可以在该属性中声明多个配置值,方法是用管道 | 字符分隔这些配置值。

例如,以下清单文件代码声明的 Activity 可同时处理屏幕方向变更和键盘可用性变更:

<activity android:name=".MyActivity"
          android:configChanges="orientation|keyboardHidden| screenSize"
          android:label="@string/app_name">

现在,当其中一个配置发生变化时,MyActivity 不会重启。相反,MyActivity 会收到对 onConfigurationChanged()的调用。

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容

  • Activity https://developer.android.com/guide/components/a...
    XLsn0w阅读 705评论 0 4
  • Activity是一个应用组件,用户可与其提供的屏幕进行交互,以执行拨打电话、拍摄照片、发送电子邮件或查看地图等操...
    进攻的蚂蚁阅读 1,154评论 0 0
  • Android之Activity系列总结(一)--Activity概览 Activity 1 创建 Activit...
    我这小样儿阅读 209评论 0 1
  • Activity是一个应用组件,用户可与其提供的屏幕进行交互。以执行拨打电话,拍摄照片,发送电子邮件或查看地图等操...
    DanieX阅读 1,095评论 0 4
  • 当我写《哲学家与终极答案》这篇文章的时候,有位简友跟我这么说。 “建议读一读王东岳先生的《物演通论》,它可以理清生...
    东非虎阅读 688评论 8 9