Android后台Kill(四):Binder讣告原理

本文详细探讨了Android中Binder的死亡通知(讣告)原理,包括注册过程和通知发送。当服务端进程异常退出,Binder驱动会向客户端发送死亡通知,确保客户端能及时作出响应。注册发生在客户端通过AMS获取服务端代理时,而通知则在服务端进程释放Binder资源时触发。客户端的DeathRecipient回调会被调用,执行相应的清理和善后工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Binder是一个类似于C/S架构的通信框架,有时候客户端可能想知道服务端的状态,比如服务端如果挂了,客户端希望能及时的被通知到,而不是等到再起请求服务端的时候才知道,这种场景其实在互为C/S的时候最常用,比如AMS与APP,当APP端进程异常退出的时候,AMS希望能及时知道,不仅仅是清理APP端在AMS中的一些信息,比如ActivityRecord,ServiceRecord等,有时候可能还需要及时恢复一些自启动的Service。Binder实现了一套”死亡讣告”的功能,即:服务端挂了,或者正常退出,Binder驱动会向客户端发送一份讣告,告诉客户端Binder服务挂了。

这个“讣告”究竟是如何实现的呢?其作用又是什么呢?对于Android而言,Binder“讣告”有点采用了类似观察者模式,因此,首先需要将Observer注册到目标对象中,其实就是将Client注册到Binder驱动,将来Binder服务挂掉时候,就能通过驱动去发送。Binder“讣告”发送的入口只有一个:在释放binder设备的时候,在在操作系统中,无论进程是正常退出还是异常退出,进程所申请的所有资源都会被回收,包括打开的一些设备文件,如Binder字符设备等。在释放的时候,就会调用相应的release函数,“讣告”也就是在这个时候去发送的。因此Binder讣告其实就仅仅包括两部分:注册与通知。

Binder"讣告"的注册入口

这里拿bindService为例子进行分析,其他场景类似,bindService会首先请求AMS去启动Service,Server端进程在启动时,会调用函数open来打开设备文件/dev/binder,同时将Binder服务实体回传给AMS,AMS再将Binder实体的引用句柄通过Binder通信传递给Client,也就是在AMS回传给Client的时候,会向Binder驱动注册。其实这也比较好理解,获得了服务端的代理,就应该关心服务端的死活 。当AMS利用IServiceConnection这条binder通信线路为Client回传Binder服务实体的时候,InnerConnection就会间接的将死亡回调注册到内核:

    private static class InnerConnection extends IServiceConnection.Stub {
   
        final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

        public void connected(ComponentName name, IBinder service) throws RemoteException {
   
            LoadedApk.ServiceDispatcher sd = mDispatcher.get();
            if (sd != null) {
   
                sd.connected(name, service);
            }
        }
    }

ServiceDispatcher函数进一步调用 doConnected

public void doConnected(ComponentName name, IBinder service) {
   
    ServiceDispatcher.ConnectionInfo old;
    ServiceDispatcher.ConnectionInfo info;
    synchronized (this) {
        
        if (service != null) {
   
            mDied = false;
            info = new ConnectionInfo();
            info.binder = service;
            info.deathMonitor = new DeathMonitor(name, service);
            try {
   
            <!-- 关键点点1-->
                service.linkToDeath(info.deathMonitor, 0);
            } 
}

看关键点点1 ,这里的IBinder service其实是AMS回传的服务代理BinderProxy,linkToDeath是一个Native函数,会进一步调用BpBinde的linkToDeath:

status_t BpBinder::linkToDeath(
    const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags){
   
    <!--关键点1--></
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值