关于 Android 进程缓存的疑问

2018-01-24 11:47:56 +08:00
 paparika
假设 app 的 task 栈里只有一个 activity,此 activity 切到后台后,系统内存短缺,决定释放这个 acitvity,那么是直接杀掉整个进程(不会触发 onDestory,下次 application 实例需要重建)还是单独 finish 掉 activity (并触发 onDestory,此时 app 进程仍在内存中,下次 application 实例无需重建)?
6476 次点击
所在节点    Android
15 条回复
zpxshl
2018-01-24 14:01:35 +08:00
一般是单独释放 activity,如果内存严重不足,直接杀进程。
lancerly
2018-01-24 14:11:20 +08:00
不同意 1 楼,不存在只 finish activity 不杀进程的情况,
内存不足,系统会按照进程优先级回收进程,
至于走不走 onDestory,不同的 rom 实现不一样,
suikator
2018-01-24 14:46:24 +08:00
kill 进程之前应该先保证栈里的 activity 已经 destory 了
jasonyang9
2018-01-24 15:01:59 +08:00
歪个楼。为什么这贴中所有的 destroy 都被写成了 destory ?
paparika
2018-01-24 15:18:40 +08:00
@lancerly 如果用 service 在通知栏里驻留一个通知,然后 activity 进后台,此时 activity 就一直常驻内存了吧
honeycomb
2018-01-24 15:36:14 +08:00
@paparika 启用开发者选项的"不保留 activity"测试一下?
s82kd92l
2018-01-24 15:57:41 +08:00
两种情况都可能出现.第一种情况系统内存不太紧张,系统会先执行 onDestroy,进程状态变为 cached process。然后系统再从所有"cached-process"里面选择杀。

当系统把所有的 cached-process 全杀光了,内存还是不够(比如 512M 的手机经常这样),系统就直接杀非空进程,根本不管你的 onDestroy 是否执行了
honeycomb
2018-01-24 15:59:31 +08:00
按照文档的说法,系统可以绕过 destroy activity 而直接杀 process。
但是也可以采取 destroy activity 的做法

https://developer.android.com/reference/android/app/Activity.html
s82kd92l
2018-01-24 16:18:01 +08:00
还有 Activity 是否执行 onDestroy 与 Application 是否重建没有因果关系。只要进程不被杀,哪怕是 cached-process,你的所有 static/singleton 的值都还在,甚至里面还能有一大堆线程继续运行任务都可以。

我一直觉得 android 里面的 service 是挂羊头卖狗肉,尤其是那些没有提供 onBind 的 service,除了向系统表达一下”我很重要别杀我”之外什么软用都没有。一个 app 可能有 10 个后台 service,但很可能只有一个线程负责处理这些 service。这样 10 个后台服务与两个效果一模一样(需要两个服务才能耍流氓,A 拉起 B,B 拉起 A )。
paparika
2018-01-24 16:19:12 +08:00
谢谢两位
@honeycomb
@s82kd92l

多问一句,假设做一个简单的单进程音乐播放 app,那么把播放逻辑做在 service 中,然后常驻一个通知,这样应该就不怕 activity 在后台被回收了,另外开启 activity 的时候去 bind 播放 service 以便获得各类播放状态显示出来(当然也可以考虑走广播机制),这个思路没什么问题吧?
paparika
2018-01-24 16:35:11 +08:00
@s82kd92l 说到 service 想起另一个问题,系统内存紧张的时候会杀掉 service,此时是整个进程一起杀还是单独杀 service 呢,如果是单独杀,如果 service 里面之前启用了一个 thread,那么被杀掉时这个 thread 发生什么了?
s82kd92l
2018-01-24 16:42:07 +08:00
@paparika 做音乐播放当然要前台 service+常驻通知,前半段思路就是官方推荐做法。我不是做 UI,后半部分我不好评价,但感觉显示播放状态应该是 service 驱动 activity,而不该让 activity 主动去 pull。是不是用 rxjava 之类的反转控制技术好些?
s82kd92l
2018-01-24 16:43:34 +08:00
如果紧张到杀带 service 的进程通常是内核绕开 android 层直接杀,整个进程都会死。
lancerly
2018-01-24 17:44:36 +08:00
<quote>
These processes often hold one or more Activity instances that are not currently visible to the user (the onStop() method has been called and returned). Provided they implement their Activity life-cycle correctly (see Activity for more details), when the system kills such processes it will not impact the user's experience when returning to that app: it can restore the previously saved state when the associated activity is recreated in a new process.
</quote>
根据文档的说法,回收内存的时候,如果实现过生命周期,那么用户返回时可以保证用户体验不被破坏,也就是说会走生命周期,

对于目前国内的 rom 来说,杀后台进程大都是直接走了 forceKill,内核直接杀,应用并不能收到任何通知,
honeycomb
2018-01-24 18:58:53 +08:00
Android 8 增加的后台限制真的是非常友好了,仅默默杀掉 service 并确保它们不再自行重新启动,但又不干涉 job

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/425504

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX