activity被回收

想象以下场景,应用中有一个活动A,用户在活动A的基础上启动了活动B,活动A就进入了停止状态,这个时候由于系统内存不足,将活动A回收掉了,然后用户按下Back键,会出现什么情况呢?其实还是会正常显示活动A的,只不过这时并不会执行onRestart()方法,而是会执行活动A的onCreate()方法,因为活动A在这种情况下会被重新创建一次。
这样看上去好像一切正常,可是别忽略了一个重要问题,活动A中是可能存在临时数据和状态的。打个比方,MainActivity中有一个文本输入框,现在你输入了一段文字,然后启动NormalActivity,这时MainActivity由于系统内存不足被回收掉,过了一会你又点击了Back键回到MainActivity,你会发现刚刚输入的文字全部都没了,因为MainActivity被重新创建了。

如果我们的应用出现了这种情况,是会严重影响用户体验的,所以必须要想想办法解决这个问题。

Activity中还提供了一个onSaveInstanceState()可以解决此问题,在此不详细解释

这里的流程其实是这样子的,A启动了B,在A的onstop之前,B的onResume之后,会调用A的onSaveInstanceState,然后A被杀死,然后点back,重新创建A,然后调用onRestoreInstanceState


参考资料

第一行代码

在 Android 系统中,当栈顶的 Activity 长时间处于静止(inactive)状态时,可能会被系统回收(destroyed),这通常是由于系统资源不足或系统策略触发的。以下是这一现象的原因分析和可能的解决方案。 ### 原因分析 1. **系统内存压力** Android 系统会在内存不足时主动回收长时间未使用的 Activity,即使它们位于任务栈的顶部。这种情况通常发生在设备内存紧张时,例如后台运行了大量应用或长时间未使用设备。 2. **系统休眠机制** 从 Android 6.0(API 23)开始,系统引入了 Doze 模式和 App Standby,以优化电池寿命。当设备处于长时间休眠状态时,系统会限制后台进程的网络访问并可能终止其组件,包括 Activity。这可能导致栈顶 Activity 被销毁 [^4]。 3. **配置变更** 如果设备在 Activity 静止期间发生了配置变更(如屏幕旋转、语言切换等),系统会默认销毁当前的 Activity 并重新创建它。如果未正确处理这些变更,可能导致用户状态丢失 [^5]。 4. **用户主动切换任务** 当用户切换到其他任务或按下 Home 键后长时间未返回,系统可能会根据最近任务管理策略回收栈顶 Activity 以释放资源 [^6]。 --- ### 解决方案 1. **保存和恢复状态** 通过重写 `onSaveInstanceState()` 方法,将关键的 UI 状态信息保存到 Bundle 中,并在 `onCreate()` 或 `onRestoreInstanceState()` 中恢复状态。这可以确保即使 Activity 被销毁后重建,用户也不会丢失数据 [^5]。 ```java @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString("user_input", userInputEditText.getText().toString()); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { String savedInput = savedInstanceState.getString("user_input"); userInputEditText.setText(savedInput); } } ``` 2. **使用 ViewModel 保存 UI 数据** Android Architecture Components 提供的 `ViewModel` 类可以在配置变更或临时销毁时保留数据。ViewModel 不会随着 Activity 的销毁而清除,只有在关联的生命周期完全结束时才会被清除 [^7]。 ```java public class MyViewModel extends ViewModel { private MutableLiveData<String> userInput = new MutableLiveData<>(); public LiveData<String> getUserInput() { return userInput; } public void saveInput(String input) { userInput.setValue(input); } } ``` 3. **使用 `onRetainNonConfigurationInstance()`(不推荐)** 此方法允许在配置变更时保留某些对象,但使用较为复杂且不适用于现代架构推荐的做法。建议优先使用 ViewModel [^5]。 4. **优化后台任务和资源占用** 确保 Activity 在非活跃状态下释放不必要的资源(如传感器监听器、定时器、网络请求等)。这可以减少系统将其回收的可能性 [^6]。 5. **处理 Doze 模式和 App Standby** 对于需要在后台持续运行的任务,可以使用 `WorkManager` 或 `Foreground Service` 来确保任务在系统限制下仍能执行。Foreground Service 会显示通知,提示用户应用正在运行 [^4]。 ```java Intent serviceIntent = new Intent(this, MyForegroundService.class); ContextCompat.startForegroundService(this, serviceIntent); ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值