到底是 Activity 被回收了还是进程被杀死了?

本文解析了Android系统中Activity与进程的关系及其在内存不足时的行为。介绍了如何通过配置让同一应用的不同Activity运行在不同进程中,并解释了系统如何决定回收哪些Activity或杀死哪些进程。

不管是安卓的官方文档还是源码注释,处处可见“从 Activity A 跳到 Activity B,当系统内存不足时 A 可能会被回收……”,而且没有明确说明 A 和 B 是否属于同一个 app 或进程。

但是,在官方给的 Activity 生命周期图中,却说内存不足时低优先级的进程将被杀死。



那么,内存不足时,到底是 Activity 被回收了呢,还是进程被杀死了呢,还是二者都出现了呢?

答案是,Activity 被回收了,而且进程被杀死了,而且一般情况下该进程是后台进程。

默认情况下,一个 app 内的所有 Activity 都属于同一个进程,不同的 app 的 Activity 属于不同的进程。

但是,即使 Activity A 和 B属于同一个 app,它们也是可以属于不同的进程的。实现方法是在 AndroidManifest 文件中通过 android:process 属性来指定不同进程。

但是,通过在 Manifest 文件中设置 android:process 属性,我们可以做到同一个 app 的 Activity 运行于不同的进程。

<activity android:name="com.tigerpenguin.lab.activitymemory.ActivityA"
          android:label="Multi Process"
          android:process=":ProcessA">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity android:name="com.tigerpenguin.lab.activitymemory.ActivityB"
          android:label="Activity B"
          android:process=":ProcessB"/>
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

当内存不足时,系统会杀死优先级低的后台进程,进程内的 Activity 肯定也就被回收了。

手机屏幕上正在显示的 Activity 所在的进程是前台进程,其余的是后台进程。

“从 Activity A 跳到 Activity B……”,这时 B 显示在屏幕上,如果 A 和 B 属于同一个进程,所以 A 和 B 所在的进程属于前台进程,所以 A 一般不会被杀死;如果 A 和 B 属于不同进程(二者可能属于同一个 app,也可能属于不同的 app),这时 A 有可能被杀死。

之所以说“前台进程一般不会被杀死……”,是因为在实际开发中,确实接到过用户投诉:正在操作的 app 发生 crash。排查后发现原因是用户机型内存过小,导致前台正在运行的 app 被杀死了。

说到这,作为一个安卓开发人员,忍不住发几句牢骚。
用户一遇到 crash 就开始骂娘、投诉,其实我们也很郁闷。
你在一个千把块钱的性能一般的手机上,开了一堆应用,手机卡了你狂喷:”看,安卓手机不行,就是不如苹果流畅……“,请问:你用过跟 iPhone 同等价位的安卓手机吗?app 崩了,你又去应用商店的评论区骂娘,去客服投诉,搞得一大群人郁闷。
难道你在买手机前就没有一个定位吗?难道你不知道一分价钱一分货?用 iPhone 1/5 的价钱买的安卓手机,却硬要跟 iPhone 比用户体验,活该你每天都活在负能量里面!

参考文献:

进程系统杀死时,App的运行状态会被强制终止,此时用户再切回App时,系统会尝试进行页面重建以恢复用户体验。Android系统提供了一定的机制来支持重建恢复,但能否完全恢复取决于以下几个因素: 1. **状态保存机制是否完善**: 页面(如Activity或Fragment)是否在被销毁前通过`onSaveInstanceState()`保存了临时状态(如UI数据)。如果未正确保存,则重建时无法恢复之前的状态。 2. **ViewModel与持久化数据**: 使用`ViewModel`可以在配置变更或短暂生命周期变化中保留数据,但如果进程被完全杀死,`ViewModel`也会被清除。此时需要依赖持久化存储(如SharedPreferences、Room数据库)来恢复关键数据。 3. **启动模式与任务栈状态**: 如果App的主Activity设置了特定的启动模式(如`singleTask`或`singleInstance`),可能会影响重建时的流程。同时,任务栈中是否还保留了历史页面也会影响恢复路径。 4. **系统资源与重建策略**: Android系统在低内存时会优先回收后台进程,重启时会尝试恢复前台可见的页面,但若系统资源紧张或App长时间未运行,可能会导致部分页面无法恢复。 ### 示例恢复流程: ```java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState != null) { // 从保存的状态中恢复数据 String userData = savedInstanceState.getString("user_data"); } else { // 首次启动或进程被杀后重建,可能需要从持久化中恢复 } } ``` ### 总结: 是的,App在进程杀死后可以进行一定程度的重建恢复,但需依赖系统提供的恢复机制和开发者是否正确实现状态保存与持久化逻辑。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值