Android Service不同进程与调用场景下崩溃行为问题咨询
Android前台运行状态下Service崩溃行为分场景结论
以下结论基于Android原生系统默认行为,定制ROM修改异常处理逻辑的场景除外:
- 场景1:Activity与Service同进程、Activity未对Service发起调用
会直接导致整个应用崩溃。同一进程内所有应用组件共享同一个ART/Dalvik虚拟机实例,进程内任意位置抛出未被捕获的异常(无论是否发生在被调用的组件中),都会触发进程级别的强制杀死流程,应用处于前台时无崩溃豁免,用户会直接感知到应用闪退。 - 场景2:Activity与Service分属同应用的两个独立进程、Activity未对Service发起调用
不会导致整个应用崩溃,仅Service所在的独立进程会被系统杀死。基于Linux进程隔离机制,不同进程的运行时环境完全独立,未建立跨进程调用关联时,Service进程的崩溃异常不会传递到Activity所在进程,Activity会保持正常前台运行,用户仅会感知到Service承载的相关功能失效,不会看到应用闪退。 - 场景3:Activity与Service同进程、Activity存在对Service的调用
一定会导致整个应用崩溃,不存在Service独立自动重启的可能。同进程场景下未捕获异常会直接终止整个进程,进程内所有组件(包括Activity、Service)会被同步销毁。注意不要混淆Service重启规则:onStartCommand返回的START_STICKY等重启标记,仅适用于系统内存不足等非崩溃场景下回收Service后的重启逻辑;如果进程因崩溃被杀死,后续即使系统根据标记尝试拉起Service,本质也是重新创建整个应用进程,这个过程中用户已经感知到闪退,不属于无感知的Service自动重启范畴。 - 场景4:Activity与Service分属同应用的两个独立进程、Activity存在对Service的调用
不会直接导致整个应用崩溃:Service所在进程会先因崩溃被杀死,Activity所在进程默认不受影响;但如果崩溃发生时Activity正持有Service的Binder引用、执行同步跨进程调用,会抛出DeadObjectException,若该异常没有在Activity侧被手动捕获,才会进一步触发Activity所在进程崩溃。只要跨进程调用时做好异常兜底捕获,Activity可以保持正常运行。
Service是否会被系统自动重启,和跨进程调用行为无关,完全取决于onStartCommand的返回值配置:返回START_STICKY或START_REDELIVER_INTENT时,系统会按规则重新拉起Service所在进程、重建Service实例;返回START_NOT_STICKY时系统不会主动重启。注意Service崩溃时,Activity侧之前注册的ServiceConnection会收到onServiceDisconnected回调,需要等Service重启完成后重新绑定才能恢复跨进程调用。
内容的提问来源于stack exchange,提问作者Kevin Ding
相关产品推荐
相关产品推荐

