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

article/2025/10/4 5:21:57

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 onDestroyjava.lang.Exceptionat 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源码)


http://chatgpt.dhexx.cn/article/3GCbX6LZ.shtml

相关文章

Activity onDestroy延迟回调

前端时间工作的时候遇到了两个奇怪的问题: 使用百度步行导航的时候,开启导航后立即退出,再次进入的时候就会黑屏;使用度小满支付的时候,当支付成功后页面一直显示loading,过了10s左右才恢复正常。 这看似…

基于MFC的OpenDDS发布订阅例子(PubSubDemo)

在编译完成Message.idl,产生MessageCommon.dll和相应的MessageTypeSupport的.h头文件和.cpp文件(MessageTypeSupportImpl.h、MessageTypeSupportC.h)的基础上,新建PubSubDemo.sln和工程PubSubDemo.vcxproj,并开始编码,实现基于Message的发布和订阅流程。 1)新建基于Dia…

OPenDDS程序 的 实现+运行

标题DDS程序实现和运行 本文记录了Windows10环境下OpenDDS环境搭建,idl自定义,代码生成,代码编写的全过程。 一、环境搭建 1.详细情况请参考开发笔记:1. OpenDDS环境搭建-Windows 10.note 编译好后生成了两个文件夹“OpenDDS-3.…

OpenDDS-1

转自:软件开发.OpenDDS 设计智能座舱时ECU之间通信及与TSP通信选择使用OpenDDS是可以的,因此不少人都认为OpenDDS是属于汽车以太网(Aumotive Ethernet,AE),但事实上autosar AE中定义中有SomeIP、DoIP、AVB…

Java程序调用OpenDDS

一、前言 前面我们用三篇博客介绍了 OpenDDS在WIndows上的环境配置 Windows下的OpenDDS编译(超详细)_山中野竹的博客-CSDN博客_opendds windows 三种方式运行发布订阅示例程序 OpenDDS运行示例(Messenger)程序_山中野竹的博客-C…

OpenDDS运行实例

因为OpenDDS是分布式的部署,所以一般发布端和订阅端都不在同一台电脑上。 我在同一台电脑上进行测试,所以ip地址为:127.0.0.1 1.发布端 1.1 新建ior文件 在根目录先新建repo.ior文件: IOR:010000001e00000049444c3a4f70656e44…

Java调用OpenDDS(1)-编译安装openDDS-补上了所有网络上其他文章遗漏的细节

Java调用OpenDDS过程中踩了很多坑,记录一下。 提纲 1、DDS简介 2、DDS协议的实现产品 3、OpenDDS安装过程 1、DDS简介 DDS指的是Data Distribution Service,也即数据分发服务,是OMG(Object Management Group,对象管理…

OpenDDS自学

前言 最近做毕设要做一个DDS系统和TISA系统的网关,完全没有基础,只好对着OpenDDS的Developers’ Guide和《分布式系统实时发布/订阅数据分发技术》这本书一点一点学(顺便吐槽这本书就是guide的翻译版,很多语句不通)。遇到很多问题&#xff0…

VS2015编译OpenDDS

最近需要研究下OpenDDS,因此需要搭建个环境,下面是一点经验,大家可以参考。 使用版本是OpenDDS-3.12、ACETAO-6.5.10和strawberry-perl,之所以使用ACETAO-6.5.10是因为往后的版本没有现成的2015对应的sln了。 一.资源下载 1.可以直接使用我…

Java调用OpenDDS(2)-理解OpenDDS自带的Messager示例

OpenDDS安装好之后,下一步就是利用OpenDDS来开发通信项目了。不过在项目中应用OpenDDS之前,先消化一下OpenDDS安装包中自带的示例项目messenger,通过阅读messenger的源代码来熟悉一下OpenDDS提供的用来开发Java项目的类。 提纲 1、准备工作 2…

OpenDDS

OpenDDS简介 Don Busch,首席软件工程师兼合作伙伴 Object Computing,Inc.(OCI) 介绍 分布式实时应用程序有时以数据为中心而不是以服务为中心,这意味着分布式系统中参与者的主要目标是分发应用程序数据,而…

OpenDDS系列(3) —— 第一个OpenDDS程序

文章目录 [toc]3.1 发送数据3.2 项目3.2.1 主题3.2.2 Publisher(发布者)3.2.3 Subscriber(订阅者) 3.3 在Windows上构建3.4 在Linux上构建3.4.1 运行 3.5 结论 3.1 发送数据 我们将创建一个主题,这是一个通过DDS交换数…

OpenDDS学习笔记(2):DDS概述

文章目录 一、DDS体系结构1.1 DLRL层1.2 DCPS层 二、DDS通信过程三、DDS通信特点四、DDS标准实现4.1 RTI DDS软件4.2 OpenSplice DDS软件4.3 OpenDDS软件 一、DDS体系结构 DDS采用DCPS通信机制,提供一个与平台无关的数据模型。它允许应用程序实时发布拥有的信息&am…

OpenDDS系列(1) —— OpenDDS 简介

1. OpenDDS简要介绍 1.1 简介 1.1.1 DDS是什么1.1.2 DDS通信的基本要素1.1.3 DDS架构的主要优点1.1.4 DDS产品种类1.1.5 OpenDDS 1.2 DDS的应用领域 美国海上战争中心(NSWC)高性能分布式计算系统(HiPer-D) 1.3 结论 1. OpenDDS简要介绍 1.1 简介 1.1.…

IDEA中查找与替换快捷键(项目全局替换、该文件下替换)

该文件下查找(CtrlF) 项目全局查找(CtrlShiftF 或【Edit】——>【Find】——>【Find in Path…】) 注意:本人电脑上的IDEA版本不支持该快捷键(CtrlShiftF),有可能是快捷键冲突…

idea实现快捷批量修改替换

1. 在当前文件内容中替换 idea替换快捷键,批量处理对象 ctrl r: 当前文件内容替换,指的是在当前打开的文件中替换匹配的字符,只操作一个文件。 2. 在路径中替换(可替换不同文件夹中的内容) ctrl shift r: 在路径中替换,指的是…

idea 查找与替换

查找当前文件内容:ctrlF 如上图片 查找全局文件:ctrlshiftF 或double shift(按两下)或ctrlshiftN替换当前文件内容 :ctrlR 如上图片 你想通过编辑器快速的将所有的’29’,变为29,你可以 ctrl…

IDEA全局替换

在做项目时,有时会在整个项目里或指定文件夹下进行全局搜索和替换,这是一个很方便功能。使用方法如下: 一、全局搜索 1、使用快捷键CtrlShiftF打开搜索窗口,或者通过点击Edit–>Find–>Find in path打开搜索窗口&#xff0…

idea 替换

idea 替换功能说明 快捷键: ctrl R界面说明

idea全局查找和替换

原文 https://blog.csdn.net/fanrenxiang/article/details/80168215 全局查找 通过快捷键 CtrlShiftf 快速进入全局查找页面,或者通过 Edit 》Find 》Find In Path 1、你要检索的内容; 2、如何匹配内容,分别表示 区分大小写、单个单词、正则、过滤查找…