Android跨进程通信Client Crash后Server端onDestroy

90 篇文章 66 订阅
42 篇文章 20 订阅

hi,粉丝朋友大家好!
好久没有给大家写blog了,哈哈,这里说声抱歉!实在家里比较忙,今天就来给大家分享一个跨进程专题课中学员问的一个问题,blog就来解答一下这个问题。
问题背景:
视频课程内容链接:https://ke.qq.com/course/package/51285?tuin=7d4eb354
binder跨进程专题的,binder的linktodeath相关

在这里插入图片描述
这里同学提出疑问:

1、为啥这个跨进程通信时候client端crash了居然会导致server端的Service执行onDestroy? 2、而且为什么onDestroy了进程还在?

其实这个同学相对还是看视频非常专心的,注意到了这个细节。
这里其实要分析出这个问题并不难,我们首先可以来回答相对好回到的问题2:

为什么onDestroy了进程还在?

这个其实就是很多同学容易犯的一个错误,就是认为Activity执行onDestroy了就说明进程退出了,进程也会死了。其实不是哈,onDstroy只是属于进程里面的一个组件的生命周期完毕,大家注意哈,这里说的一个组件而不是进程的生命周期,即进程不会因为组件的onDestroy而进程也died,所以这里大家要注意哈

接下来在分析第一个问题

为啥这个跨进程通信时候client端crash了居然会导致server端的Service执行onDestroy?

总结一下就是为啥客户端死了会导致Service组件执行onDestroy,其实要想通这个问题并不难,首先从宏观上来看:
客户端 —bindService—才启动的Serivce执行的onCreate和onBind,但是现在客户端死了,那么大家想想那这个Serivce组件是不也应该要unbind和onDestroy呢?是不是这样想也其实挺合理
但是这个只是宏观上的一个理解感觉这样设计合理,但是请问老师你是嘴巴说么,有没有证据证明你说的这个,其实就是那句程序员名言:
talk is cheap,show me the code!
哈哈,那接下来就看我是show the code

分析步骤:
1、服务端service的onDestroy执行是谁调用过来的?
这个比较简单其实就使用课程经常使用的普通打印堆栈就可以

022-07-23 00:18:10.333 22650-22650/com.example.servicedemo I/test1: MyService onDestroy
    java.lang.Exception
        at com.example.servicedemo.MyService.onDestroy(MyService.java:126)
        at android.app.ActivityThread.handleStopService(ActivityThread.java:4669)
        at android.app.ActivityThread.access$2100(ActivityThread.java:247)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2096)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7839)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

大家发现这里其实是ActivityThread.handleStopService,这里其实大家大概知道,它对应的其实是:

   public final void scheduleStopService(IBinder token) {
            sendMessage(H.STOP_SERVICE, token);
        }

scheduleStopService这个方法调用导致,而scheduleStopService其实属于systemserver跨进程通信调用过来的
那么接下来就应该去framework中去搜索一下谁调用了scheduleStopService

test@test:~/aosp/frameworks$ grep scheduleStopService ./ -rn
./base/boot/hiddenapi/hiddenapi-max-target-o.txt:1933:Landroid/app/ActivityThread$ApplicationThread;->scheduleStopService(Landroid/os/IBinder;)V
./base/boot/hiddenapi/hiddenapi-max-target-o.txt:6200:Landroid/app/IApplicationThread$Stub$Proxy;->scheduleStopService(Landroid/os/IBinder;)V
./base/boot/hiddenapi/hiddenapi-max-target-o.txt:6254:Landroid/app/IApplicationThread$Stub;->TRANSACTION_scheduleStopService:I
./base/boot/boot-image-profile.txt:862:HSPLandroid/app/ActivityThread$ApplicationThread;->scheduleStopService(Landroid/os/IBinder;)V+]Landroid/app/ActivityThread;Landroid/app/ActivityThread;
./base/services/core/java/com/android/server/am/ActiveServices.java:4303:                    r.app.getThread().scheduleStopService(r);
./base/config/boot-image-profile.txt:862:HSPLandroid/app/ActivityThread$ApplicationThread;->scheduleStopService(Landroid/os/IBinder;)V+]Landroid/app/ActivityThread;Landroid/app/ActivityThread;
./base/core/java/android/app/ActivityThread.java:1085:        public final void scheduleStopService(IBinder token) {
./base/core/java/android/app/IApplicationThread.aidl:73:    void scheduleStopService(IBinder token);
./base/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java:445:        public void scheduleStopService(IBinder iBinder) throws RemoteException {

大家可以看出结果其实非常明确就是
./base/services/core/java/com/android/server/am/ActiveServices.java:4303: r.app.getThread().scheduleStopService®;
即ActiveServices中进行了调用的,所以我们就好办,要么打印堆栈也可以,或者大家直接我经常交大家的采用更加先进的debug systemserver也可以
这里我们采用debug方式:
在这里插入图片描述

具体是怎么调用的大家可以看一下堆栈然后自己跟一下就可以

大概意思就是:
systemserver其实也对client的binder对象进行了linkToDeath,当client crash 时候systemserver也是要对这个进程Application修改记录信息进行扫尾处理,cleanup的,这里面就包含了我们今天问题Service执行onDestroy,因为Serivce本身是由Client发起的绑定拉起,

*## 而且也没有其他客户端绑定Service了 *

,当然唯一的链条Client如果已经died了,那么Service也就没有再存在,执行对应的unbind和onDestroy

新课程优惠获取请加入qq群:422901085(获取demo源码)

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值