Android Saving Activity State使用说明和注意事项

1、说明

在管理activity生命周期的简单介绍中提到当一个activity被暂停或停止时,该activity的状态被保留。因为当activity对象被暂停或停止时仍然保留在内存中,所有有关成员的信息和当前的状态仍然可用。这样,用户对该activity所做的任何更改都会保留并当恢复时这些变化仍然存在。

然而,当系统为了恢复内存而销毁activity对象时,该activity对象就被销毁了,因此系统不能简单的通过状态恢复它。相反,当用户从新回到该界面时系统必须重新创建activity对象。然而,用户并不知道系统销毁了该activity对象并重新创建了它,这样,很可能期望这个界面就是之前的那个。在这种情况下,必须保证有关activity状态的重要信息通过实现额外的回调函数来保存有关activity状态的信息:onSaveInstanceState()。

在该activity受到破坏之前调用onSaveInstanceState()方法。系统传递一个Bundle对象到该方法,一个Bundle利用putString()和putInt()方法以键值对的形式保存activity的状态信息。这时,当系统杀掉应用程序进程,用户又回到之前的界面,系统重新创建一个activity并传递Bundle到onCreate()和onRestoreInstanceState()方法。利用任一个方法,可以从Bundle中提取保存的状态信息并恢复该Activity的状态。如果没有状态信息需要恢复,这时传递的Bundle是null(当第一次创建activity时)。

在这里插入图片描述
然而,即便你没做任何事情并且也没有实现onSaveInstanceState(),一些activity状态也会通过activity类默认的onSaveInstanceState()实现来存储。具体来说,默认的实现为布局中的每个View调用相应的onSaveInstanceState()方法,在该方法里每个view提供需要保存的自身的信息。几乎Android框架中的每个组件都适当的实现了该方法,例如,UI上的任何可视的变化都能自动的保存并在该Activity重新创建时恢复。例如,EditText部件保存用户输入的任何文本,CheckBox保存是否被选中。你需要做的唯一工作是为每个需要保存状态的组件提供一个唯一的ID(利用android:id属性),如果一个组件没有ID,系统不能保存它的状态(一般情况是xml上提供一个ID,如果是代码上布局的组件,就用setId(int id)提供一个ID)。

虽然onSaveInstanceState()默认实现能够保存Activity的一些有用信息,但还是需要覆盖它保存一些额外的信息。例如,需要在activity生命周期中保存更改的成员值(这需要在UI中恢复这些值相关,但是持有这些值的成员不会被恢复)。

如果重新了onSaveInstanceState()方法,在实现中应该调用父类的方法,以存储默认的信息。同时在onRestoreInstanceState()中也调用父类的方法以恢复默认的信息。

注意:由于onSaveInstanceState()方法不保证一定会被调用,你应该用它只记录activity的临时状态而不是持久数据。相反,在onPause()里来存储持久数据。

测试应用程序恢复状态能力的好方法是简单的旋转设备以使屏幕方向改变。当方向改变时,系统销毁并重新创建这个Activity以应用可选的资源,这些资源在新屏幕配置中使用。出于这个原因,当activity重新创建时完全恢复其状态是很重要的,应用用户在使用应用时经常旋转屏幕。

Handling configuration changes

有些设备配置在运行时会改变(例如,屏幕方向,键盘可用性,和语言)。当这些变化发生时,Android重新创建这个运行着的Activity(系统调用onDestroy(),然后立即调用onCreate()),这种行为可以帮助应用程序采用新的配置,通过自动加载应用程序利用你提供的可选资源(不同的屏幕和大小采用不同的布局)。

如果你能正确的设计activity来处理由于屏幕方向变化和恢复activity状态导致的重启,你的应用程序会对activity生命周期中的突发事件更有弹性。

处理这种重启事件最好的方法就是存储和恢复你的activity的状态,通过调用onSaveInstanceState()和onRestoreInstanceState()(或onCreate())。

当一个activity启动另一个,他们都需要进行生命周期转换。第一个activity暂停和停止。而另一个activity被创建。这种情况下这些activities共享保存到光盘或其他地方的数据,重要的是理解在第二个activity被创建之前第一个activity是没有完全停止的。相反,启动第二个的过程和停止第一个的过程是重叠的。

生命周期中回调的顺序需要友好定义,特别是当两个activities在同一个进程里,一个启动另一个。下面是当A启动B时的顺序:
1, A的onPause()方法执行
2, B的onCreate(),onStart()和onResume()方法执行
3, 这时,如果A在屏幕上已不可见,onStop()方法执行。

2、实操

2.1、使用 onSaveInstanceState() 保存简单轻量的界面状态

当您的 Activity 开始停止时,系统会调用 onSaveInstanceState() 方法,以便您的 Activity 可以将状态信息保存到实例状态 Bundle 中。此方法的默认实现保存有关 Activity 视图层次结构状态的瞬时信息,例如 EditText 微件中的文本或 ListView 微件的滚动位置。

如需保存 activity 的其他实例状态信息,请替换 onSaveInstanceState(),并将键值对添加到在 activity 意外销毁时保存的 Bundle 对象。替换 onSaveInstanceState() 时,如果您希望默认实现保存视图层次结构的状态,则需要调用父类实现。具体可见以下示例:

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, currentScore);
    savedInstanceState.putInt(STATE_LEVEL, currentLevel);

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

注意 :当用户显式关闭 activity 或其他情况下,当调用 finish() 时,系统不会调用 onSaveInstanceState()。

如需保存持久性数据(例如用户偏好设置或数据库的数据),请在 activity 位于前台时抓住适当的机会。如果没有这样的时机,请在使用 onStop() 方法期间保存持久性数据。

2.2、使用保存的实例状态恢复 Activity 界面状态

重建先前被销毁的 Activity 后,您可以从系统传递给 Activity 的 Bundle 中恢复保存的实例状态。onCreate() 和 onRestoreInstanceState() 回调方法都会接收包含实例状态信息的同一 Bundle。

由于无论系统是创建新的 activity 实例还是重新创建之前的实例,都会调用 onCreate() 方法,因此您需要先检查状态 Bundle 是否为 null,然后再尝试读取它。如果为 null,系统将新建 Activity 实例,而不会恢复之前销毁的实例。

以下代码段展示了如何在 onCreate() 中恢复某些状态数据:

@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.
        currentScore = savedInstanceState.getInt(STATE_SCORE);
        currentLevel = savedInstanceState.getInt(STATE_LEVEL);
    } else {
        // Probably initialize members with default values for a new instance.
    }
    // ...
}

您可以选择实现系统在 onStart() 方法之后调用的 onRestoreInstanceState(),而不是在 onCreate() 期间恢复状态。仅当存在要恢复的已保存状态时,系统才会调用 onRestoreInstanceState(),因此您无需检查 Bundle 是否为 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.
    currentScore = savedInstanceState.getInt(STATE_SCORE);
    currentLevel = savedInstanceState.getInt(STATE_LEVEL);
}

注意:请始终调用 onRestoreInstanceState() 的父类实现,以便默认实现可以恢复视图层次结构的状态。

觉得本文对您有用,麻烦点赞、关注、收藏,您的肯定是我创作的无限动力,谢谢!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/623612.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

全国大学生数学建模竞赛【集训营E题】丨 近5年赛题实现,模拟参赛体验

全国大学生数学建模竞赛E题集训营即将开营 基于Python的近5年E题数学建模基础巩固 近5年E题赛题实现 模拟参赛体验与作品评审

Ansys Zemax|HUD 设计实例

说明 本文介绍了HUD设计实例。 实例说明 规格如下: 显示器尺寸:24*8mm 眼盒尺寸:100*40mm 放大倍率:5 (虚像尺寸 120*40mm) 虚像距离:1.8m 最终光学系统的整体布局如下图所示。 从HUD发出的…

【Linux取经路】文件中的数据是如何被写进磁盘的?

文章目录 一、操作系统对物理内存的管理1.1 物理内存与磁盘的数据交换1.2 操作系统对物理内存的管理 二、再来看文件打开和写入2.1 文件页缓冲区的引入2.2 向文件中写入的过程 三、结语 一、操作系统对物理内存的管理 1.1 物理内存与磁盘的数据交换 物理内存与磁盘之间的数据…

专业的服贸会服务团队-媒体邀约宣传

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 2024服贸会开展在即,许多企业都做好了的参展的准备,北京麦塔文化提供专业的展览展会服务,下面做个简单介绍。 、会场搭建团队: 负责整个活…

如何完美实现文件外发防泄漏,保护核心数据资产?

不管是大型企业,还是小型创业公司,不论企业规模大小,每天都会有大量的文件要进行内部传输协作和对外发送使用,数据的生产也是企业业务生产力的体现之一。因此文件外发防泄漏是企业信息安全中的一个重要议题,为了防止企…

MTATLAB--一元线性回归分析

一文让你彻底搞懂最小二乘法(超详细推导) 在进行一元线性回归分析时,使用最小二乘法进行解题,关于最小二乘法具体看上述文章。 数据文件在文章顶部可见,将第一列数据作为自变量x,第二列数据作为应变量y。建…

软件设计师备考笔记(四):操作系统知识

文章目录 一、操作系统概述(一)操作系统的基本概念(二)操作系统分类及特点 二、进程管理(一)基本概念(二)进程的控制(三)进程间的通信(四&#xf…

C语言易错提醒选择题精选

Ⅰ 易错题 1.设有double p;&#xff0c;为变量p声明一个引用名称rp,则定义语句为 double& rpp; 2.已知‘A’一‘Z’的ASCII码为65—90&#xff0c;当执行“char ch14*52&#xff1b;cout<<ch<<endl;”语句序列后得到的输出结H &#xff0c;72对应ASCII码中…

研发管理-选择研发管理系统-研发管理系统哪个好

选择研发管理系统-研发管理系统哪个好 选择研发管理系统时&#xff0c;并没有一个绝对的“最好”的系统&#xff0c;因为每个企业的需求和情况都是独特的。然而&#xff0c;我可以向您介绍一些在市场上广受欢迎且功能强大的研发管理系统&#xff0c;供您参考&#xff1a; 1、彩…

答辩PPT快速生成工具有哪些?笔灵AI答辩PPT,一键搞定

很多快要毕业的同学在做答辩PPT的时候总是感觉毫无思路&#xff0c;一窍不通。但这并不是你们的错&#xff0c;对于平时没接触过相关方面&#xff0c;第一次搞答辩PPT的人来说&#xff0c;这是很正常的一件事。一个好的答辩PPT可以根据以下分为以下几部分来写。 1.研究的背景和…

微信小程序发送订阅消息sendMessage

微信小程序发送订阅消息sendMessage 请注意订阅消息一次性订阅只只能授权一次接受一条消息多次授权会累加接受次数&#xff0c;wx.requestSubscribeMessage调用授权 目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放 //授权弹框&#xff0c;只弹出…

大语言模型的数据预处理

文章目录 质量过滤敏感内容过滤数据去重 当收集了丰富的文本数据之后&#xff0c;为了确保数据的质量和效用&#xff0c;还需要对数据进行预处理&#xff0c;从而消除低质量、冗余、无关甚可能有害的数据。一般来说&#xff0c;需要构建并使用系统化的数据处理框架&#xff08;…

AI浪潮再起,2024年中国大模型产业深度解析

国内 AI大模型产业发展深度分析 2024 人工智能技术的迅猛发展&#xff0c;使AI大模型成为科技竞争的核心、产业变革的先锋、经济增长的新动力。我国已将人工智能列为国家战略&#xff0c;出台系列政策扶持其发展&#xff0c;为AI大模型产业创造优越环境&#xff0c;展现巨大潜力…

手撕C语言题典——链表的中间节点

目录 前言 一.思路 1)用指针遍历链表&#xff0c;创建 count 计数&#xff0c;返回 count/2->next 即为中间节点 2&#xff09;快慢指针 二.代码实现 1&#xff09;思路一 2&#xff09;思路二 搭配食用更佳哦~~ 数据结构之单单单——链表-CSDN博客 数据结构之单链表的…

CorelDRAW2024新特性全解析!

CorelDRAW2024是一款备受赞誉的图形设计软件&#xff0c;它以其强大的功能和用户友好性赢得了全球数百万设计师的青睐。该软件提供了丰富的绘图、排版、图像处理、矢量编辑以及网页设计工具&#xff0c;无论是初学者还是专业设计师&#xff0c;都能在这款软件中找到满足自己需求…

openai春季发布会:GPT-4o(更快,更强,更便宜)

人工智能学习网站 https://chat.xutongbao.top

计算机毕业设计 | springboot+vue电影院会员管理系统 影院后台管理(附源码)

1&#xff0c;项目背景 随着互联网时代的到来&#xff0c;同时计算机网络技术高速发展&#xff0c;网络管理运用也变得越来越广泛。因此&#xff0c;建立一个B/S结构的电影院会员管理系统&#xff1b;电影院会员管理系统的管理工作系统化、规范化&#xff0c;也会提高影院形象…

江苏省人大财经委主任委员谢志成一行莅临聚合数据走访调研

4月18日&#xff0c;江苏省人大财经委主任委员谢志成莅临聚合数据展开考察调研。省人大财经委副主任委员&#xff08;正厅&#xff09;周毅、省人大常委会办公厅一级巡视员吕小鹏、外事委委员赵正驰、省数据局副局长王万军&#xff1b;苏州市人大常委会副秘书长毛元龙、数据局副…

vue2 报错,警告 解决方法 component name“Index“should always be multi-word

报错原因&#xff1a; 组件名称应该为俩个或俩个以上单词组成的&#xff0c;并且还要是大驼峰命名&#xff0c;例如&#xff1a;MyIndex&#xff0c;MyLogin等 解决方法一&#xff1a; 将组件名称改为俩个或俩个以上单词组成的名称&#xff0c;且为大驼峰命名&#xff0c;例如…

钽酸锂集成光子芯片:引领光电集成新纪元

在信息技术飞速发展的今天&#xff0c;光电集成技术已成为推动全球集成电路产业持续创新的重要力量。随着全球集成电路产业发展步入“后摩尔时代”&#xff0c;芯片性能提升的难度和成本不断攀升&#xff0c;业界急需寻找新的技术突破口。在这一背景下&#xff0c;中国科学院上…