Android Activity被回收后的处理

本文解析了Android系统中Activity被自动回收的原因及过程。系统在内存不足时会回收后台App中的Activity来释放资源,同时保留任务栈以便恢复。文章强调了开发者需要注意UI状态的保存与恢复,特别是对于非UI相关的变量和子线程的处理。
  1. Activity为什么会被自动回收

处于后台App中的Activity会在系统内存不足时,被系统回收。

看看源码就知道咯~~~~当前使用的内存,超过最大内存的3/4就会开始自动回收activity呀

 // Watch for getting close to heap limit.

            BinderInternal.addGcWatcher(new Runnable() {
                @Override public void run() {
                    if (!mSomeActivitiesChanged) {
                        return;
                    }
                    Runtime runtime = Runtime.getRuntime();
                    long dalvikMax = runtime.maxMemory();
                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                    if (dalvikUsed > ((3*dalvikMax)/4)) {
                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                                + " total=" + (runtime.totalMemory()/1024)
                                + " used=" + (dalvikUsed/1024));
                        mSomeActivitiesChanged = false;
                        try {
                            mgr.releaseSomeActivities(mAppThread);
                        } catch (RemoteException e) {
                        }
                    }
                }
            });

2. 返回被回收的Activity时,系统如何处理。

当内存不足的时候位于后台的应用会被系统回收掉,只是保留着任务栈,再次进入的时候会恢复它们。

要注意的地方有:系统只会把ui相关的东西存起来和恢复,其他的一些成员变量都不会管。

会把生命周期和创建一样重新走一遍,这个时候得注意那些不是从onCreat这样的生命周期方法中获得的变量状态了,譬如那些运行的时候从网络获取或者是其他模块传过来的,最好在onSaveInstantstate中存起来。

注意那些子线程,一个在activity或者fragment中长期运行的子线程,会让你的组件得不到释放,并且在重新创建恢复的过程中随着状态的一些更改,譬如旧的fragment从activity中剥离了,持有旧fragment引用的子线程这个时候调用fragment的时候就会有getActivity()返回为空等问题了。


总结:模块间的数据传送,最好使用系统提供的intent这样的载体,有那些无法随着生命周期的创建被恢复的变量时尽量将它通过saveInstanceBundle保存起来,在重新创建的时候可以恢复。或者做好预防机制,比如网络请求的数据没有了,这个时候可以重新加载请求。


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、付费专栏及课程。

余额充值