savedInstanceState 的作用

笼统定义:在每个Activity对象被killed之前(有条件的),savedInstanceState 用来保存每个对象的状态。

 

举个例子,有两个activity的实例,分别为A,B, A先启动,然后B再启动遮挡住了A, 这时候如果系统的内存不足,系统就会暂时回收A,因为此时A是被遮挡的,对用户不可见的! 在回收A之前要做一些保存实例状态的工作,因为在B回返的时候,A还是要被重新创建并显示给用户的。

 

在activiy被回收的时候,它会调用 onSaveInstanceState(Bundle)  这个回调保存activity的状态,在恢复的时候会调用  onRestoreInstanceState(Bundle)  这个回调恢复系统状态,他们都是有默认实现的,如果你要添加非默认的状态,需要在这两个方法里自己添加。

<think> 在Android开发中,`savedInstanceState`为null是正常现象。以下是详细解释: ### 何时为null? 1. **首次启动Activity/Fragment时** - 当用户首次打开应用或通过Intent启动新Activity时 - 系统不会提供保存的实例状态Bundle 2. **彻底退出后重启** - 当应用进程被系统杀死后重新创建 - 如果此前未调用`onSaveInstanceState()`保存数据,则Bundle为null 3. **配置变化未保存状态** - 旋转屏幕等配置变化时,若未重写`onSaveInstanceState()`方法 ### 何时不为null? | 场景 | 触发条件 | |--------------------------|----------------------------------| | 后台回收重启 | 系统资源不足时回收Activity | | 配置变化自动保存 | 屏幕旋转/语言切换等 | | 从最近任务重启 | 用户从最近任务列表重新打开应用 | | 显式保存状态 | 调用`onSaveInstanceState()` | ### 正确使用模式: ```java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState != null) { // 恢复保存的数据 String data = savedInstanceState.getString("key"); } else { // 初始化新数据 } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString("key", "需要保存的数据"); } ``` ### 注意事项: 1. **Fragment特殊处理**: ```java @Override public void onViewStateRestored(@Nullable Bundle savedInstanceState) { super.onViewStateRestored(savedInstanceState); // Fragment中恢复UI状态的最佳位置 } ``` 2. **ViewModel替代方案**: ```java // 对于配置变化导致的重建,建议使用ViewModel public class MyViewModel extends ViewModel { private String persistentData; public String getData() { return persistentData; } public void setData(String data) { persistentData = data; } } ``` ### 生命周期对比: ``` 首次启动:onCreate(savedInstanceState == null) 旋转屏幕:onCreate(savedInstanceState != null) 后台被杀重启:onCreate(savedInstanceState != null) ``` ### 常见误区: - 误以为所有重建场景savedInstanceState都不为null - 在onCreate()中试图恢复Fragment(应使用setRetainInstance(true)) - 保存大型数据(应保存最小必要数据,限制<50KB) §§相关问题§§ 1. Bundle对象可以保存哪些类型的数据? 2. 为什么在onRestoreInstanceState()中恢复UI状态更合适? 3. ViewModel如何解决配置变化导致的数据丢失问题? 4. 如何测试savedInstanceState为null的场景? 5. Fragment的setRetainInstance(true)有什么作用? </think> 在Android开发中,`savedInstanceState`为**null是完全合理且常见的情况**。以下是详细解释: ### 何时savedInstanceState为null是合理的? 1. **首次启动Activity/Fragment时** 当用户首次打开应用或通过Intent启动新Activity时: ```java // onCreate方法中 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 首次启动时savedInstanceState == null } ``` 2. **正常流程退出后重启** 当用户按返回键退出应用后重新打开: ```java // 用户按返回键 -> onDestroy()被调用 // 重新启动时savedInstanceState == null ``` 3. **强制停止应用后** 通过设置 -> 应用 -> 强制停止后重启: ```java // 系统不会保存状态,savedInstanceState == null ``` 4. **未实现状态保存时** 如果没有重写`onSaveInstanceState()`: ```java @Override protected void onSaveInstanceState(Bundle outState) { // 未调用super也未保存数据 // 重建时savedInstanceState == null } ``` ### 何时savedInstanceState不为null? | 场景 | 触发条件 | 状态值 | |-----------------------|-----------------------------------|------------------| | 配置变化 | 屏幕旋转/语言切换 | Bundle不为null | | 后台被系统回收 | 系统资源不足时 | Bundle不为null | | 从最近任务列表恢复 | 用户切换应用后返回 | Bundle不为null | | 开发者显式保存状态 | 调用`onSaveInstanceState()` | Bundle不为null | ### 最佳实践建议: 1. **正确处理null情况** ```java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState == null) { // 初始化新状态 initData(); } else { // 恢复保存的状态 restoreData(savedInstanceState); } } ``` 2. **正确保存状态** ```java @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // 必须调用super! outState.putString("USER_NAME", currentUserName); outState.putInt("SCROLL_POSITION", recyclerViewPosition); } ``` 3. **ViewModel替代方案** 对于配置变化导致的重建: ```java public class MyViewModel extends ViewModel { private MutableLiveData<String> userName; public LiveData<String> getUserName() { if (userName == null) { userName = new MutableLiveData<>(); loadUserName(); } return userName; } } ``` ### 特殊注意事项: 1. **Fragment区别** Fragment有两种状态恢复位置: ```java @Override public void onCreate(@Nullable Bundle savedInstanceState) { // savedInstanceState可能为null } @Override public void onViewStateRestored(@Nullable Bundle savedInstanceState) { // 这里恢复视图状态更安全 } ``` 2. **Jetpack Compose** 在Compose中恢复状态: ```kotlin val savedState = rememberSaveable { mutableStateOf("") } ``` 3. **测试建议** 使用以下方法测试状态恢复: ```java // 模拟配置变化 ActivityScenario<MyActivity> scenario = ActivityScenario.launch(MyActivity.class); scenario.recreate(); // 触发状态保存/恢复 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值