V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
paparika
V2EX  ›  Android

关于 Android 进程缓存的疑问

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

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

    https://developer.android.com/reference/android/app/Activity.html
    s82kd92l
        9
    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
        10
    paparika  
    OP
       2018-01-24 16:19:12 +08:00
    谢谢两位
    @honeycomb
    @s82kd92l

    多问一句,假设做一个简单的单进程音乐播放 app,那么把播放逻辑做在 service 中,然后常驻一个通知,这样应该就不怕 activity 在后台被回收了,另外开启 activity 的时候去 bind 播放 service 以便获得各类播放状态显示出来(当然也可以考虑走广播机制),这个思路没什么问题吧?
    paparika
        11
    paparika  
    OP
       2018-01-24 16:35:11 +08:00
    @s82kd92l 说到 service 想起另一个问题,系统内存紧张的时候会杀掉 service,此时是整个进程一起杀还是单独杀 service 呢,如果是单独杀,如果 service 里面之前启用了一个 thread,那么被杀掉时这个 thread 发生什么了?
    s82kd92l
        12
    s82kd92l  
       2018-01-24 16:42:07 +08:00
    @paparika 做音乐播放当然要前台 service+常驻通知,前半段思路就是官方推荐做法。我不是做 UI,后半部分我不好评价,但感觉显示播放状态应该是 service 驱动 activity,而不该让 activity 主动去 pull。是不是用 rxjava 之类的反转控制技术好些?
    s82kd92l
        13
    s82kd92l  
       2018-01-24 16:43:34 +08:00   ❤️ 1
    如果紧张到杀带 service 的进程通常是内核绕开 android 层直接杀,整个进程都会死。
    lancerly
        14
    lancerly  
       2018-01-24 17:44:36 +08:00   ❤️ 1
    <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
        15
    honeycomb  
       2018-01-24 18:58:53 +08:00 via Android
    Android 8 增加的后台限制真的是非常友好了,仅默默杀掉 service 并确保它们不再自行重新启动,但又不干涉 job
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1530 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 17:04 · PVG 01:04 · LAX 10:04 · JFK 13:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.