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() 的父类实现,以便默认实现可以恢复视图层次结构的状态。

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

笔记:完善python selenium 讯飞写作的整体自动化

昨天做得不太好,今天再来一次,我发现,只要写得多,一定会有发现。 1、加入本地目录,不要一直登录。 # 定义Edge浏览器的用户数据目录edge_user_data_dir = r"C:\Users\Administrator\AppData\Local\Microsoft\Edge\User Data\Default"# 设置Edge选项edge_optio…

Spire.PDF for .NET【文档操作】演示:将多个 PDF 文件中的选定页面合并为一个

使用 Spire.PDF,您不仅可以将多个 PDF 文件合并为一个文件,还可以从源文件中选择特定页面并将它们合并为一个 PDF 文档。以下代码片段演示了相同的内容。 Spire.PDF for .NET 是一款独立 PDF 控件,用于 .NET 程序中创建、编辑和操作 PDF 文档…

腐烂的橘子 - (LeetCode)

一、概述 994. 腐烂的橘子 - 力扣(LeetCode),今天刷到这道题,开始按照自己实现的思路写了一次,通过了调试,但是提交的时候,来了一个大的数据,就没有通过测试,百思不得其…

牛顿/高斯牛顿/LM法与最小二乘

最小二乘分为线性最小二乘和非线性最小二乘 最小二乘目标函数都是min||f(x)||2 若f(x) ax b,就是线性最小二乘;若f(x) ax2 b / ax2 bx 之类的,就是非线性最小二乘; 求解线性最小二乘,【参考】 求解非线性最小二…

【多人协作】场景模拟(一)

文章目录 实现多人协作场景:操作流程1开发人员a和b克隆仓库到本地2在本地仓库建立分支并与远程分支建立链接3开发人员工作并提交代码4将合并dev分支与master分支 实现多人协作 多人协作开发是git的最核心也是最重要的操作。多人协作也就意味着同一时间里&#xff0…

游戏私域运营干货必看 | 《 2023 中国移动游戏私域运营指南》下载

在新游竞争越发激烈、买量效率持续走低、用户注意力资源紧缺等悬而未决的现实困境下,游戏企业必须在存量市场中,寻找一条可行、可复制的出路。 为了一探究竟,网易云商分别面向国内 23 家中大型研运一体化游戏公司,与 2000 位真实…

红黑树!!

文章目录 1.红黑树的概念2.红黑树的几种情况2.1 情况一:cur为红,p为红,g为黑,u存在且为红(p为parent,g为grandfather,u为uncle)2.2 情况二:cur为红,p为红,g为黑&#xff…

MATLAB支持向量机:函数或变量 ‘svmtrain‘ 无法识别解决方法

我的MATLAB版本是2020a,在运行程序时出现了一下报错 若在运行程序时出现了以下报错: 支持向量机程序在MATLAB执行代码的时候发现有错误。 试一下help,如下图所示,SVM_L和svmtrain均找不到。 打开matlab帮助文档: 可…

C# XPTable in .net6(XPTable控件使用说明八)

经过作者schoetbi、armin-pfaeffle的努力,XPTable已经可以在 winform .net6 .net8的环境下使用,版本升级到了2.0,这样就可以在winform下同时使用XPTABLE和EFcore, 这样就可以解决大部分的场景了。

【HMGD】GD32/STM32 DMA接收不定长串口数据

单片机型号:GD32F303系列 CubeMX配置 配置串口参数 开启DMA 开启中断 示例代码 使用到的变量 uint8_t RX_Buff_FLAG 0; uint8_t RX_Buff[300] {0}; uint8_t TX_Buff[300] {0};串口接收空闲函数 // 串口接收空闲函数 void HAL_UARTEx_RxEventCallback(UART_H…

邮件地址采集软件有哪些-邮箱地址采集软件

邮件地址采集软件是帮助用户收集、管理和使用邮件地址的工具,它们在商业营销、市场调研、网络爬虫等领域有着广泛的应用。以下是一些常见的邮件地址采集软件: 易邮件地址搜索大师:易邮件地址搜索大师是一款搜索邮件地址和手机号码的软件&…

数据库开发记录

一.MySQL相关 1.Spatial Data相关

OpenAI发布最强大模型GPT-4o:对所有用户免费

OpenAI 最新推出的 GPT-4o 模型在实现更自然的人机交互方面迈出了重要一步。GPT-4o的“o” 源自拉丁语“全方位”,意思是“一切”。活动期间 OpenAI, 米拉穆拉蒂该公司技术总监上台展示了新的语言模型。她强调,拥有 OpenAI 帐户的每个人都可以免费使用新…

安装adobe系列,提示错误代码146解决办法

安装Adobe系列产品如PS、PR、Lrc等产品时,会因为各种各样的错误导致安装失败!今天小编为大家带来的是安装adobe系列,提示错误代码146解决办法,收藏起来吧! 方法一:就是传说中的万能大法,关机重启…

【MySQL】sql表设计的注意事项

程序员的实用神器 文章目录 程序员的实用神器强烈推荐引言注意事项强烈推荐专栏集锦写在最后 强烈推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站:人工智能 推荐一个个人工作&#x…

五、Linux二进制安装MariaDB 六、MariaDB主从复制

目录 五、Linux二进制安装MariaDB1 卸载mariadb1.1 卸载相关的服务(mysql和mariadb都查询一下)1.2 查找MySQL和mariadb相关的文件目录 2 安装mariadb2.1 mariadb下载地址2.2 将安装包放入到服务器中并解压 (我放到opt下)2.3 将解压后的目录移动到安装目录下2.4 创建数据目录(根…

高效且安全的传输工具:FileLink跨网文件传输

在数字化时代,文件传输已成为我们日常工作和生活不可或缺的一部分。无论是企业内部的资料共享,还是企业对外的文件交换,都需要一个高效、稳定且安全的传输工具。而FileLink跨网文件传输正是满足这些需求的理想选择。 FileLink跨网文件传输 首…

雇佣 K 位工人的总代价

题目链接 雇佣 K 位工人的总代价 题目描述 注意点 costs[i]是雇佣第 i 位工人的代价每一轮雇佣后,剩余工人的下标可能会发生变化一位工人只能被选择一次如果剩余员工数目不足 candidates 人,那么下一轮雇佣他们中代价最小的一人如果有多位代价相同且最…

IOS 苹果IAP(内购)之创建沙盒账号

IOS 苹果IAP(内购)之创建沙盒账号 沙盒账号是什么?沙盒账号创建的前提条件沙盒账号创建沙盒账号使用流程沙盒账号注意事项 沙盒账号是什么? 如果IOS应用里面用到了苹果应用内付费(IAP)功能,那么…

上位机图像处理和嵌入式模块部署(树莓派4b的替代品)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 实话实说,树莓派4b的产品力还是比较优秀的,价格还算适中。但是和国产卡片电脑比起来,则逊色不少。功能差不多的…