android linktodeath 客户端kill,使用IBinder的linkToDeath机制来释放资源

ThelinkToDeath()method can be used to register aIBinder.DeathRecipientwith the IBinder, which will be called when its containing process goes away.

就是说我们通过systemService申请了某个service的Binder后,可以调用这个IBinder的linkToDeath函数进行注册。可以注册一个IBinder.DeathRecipient类型的对象。其中IBinder.DeathRecipient是IBinder类中定义的一个嵌入类。

public abstract voidlinkToDeath (IBinder.DeathRecipient recipient, int flags)

Register the recipient for a notification if this binder goes away. If this binder object unexpectedly goes away (typically because its hosting process has been killed), then the given IBinder.DeathRecipient's DeathRecipient.binderDied() method will be called.

You will only receive death notifications for remote binders, as local binders by definition can't die without you dying as well.

当这个IBinder所对应的Service进程被异常的退出时,比如被kill掉,这时系统会调用这个IBinder之前通过linkToDeath注册的DeathRecipient类对象的binderDied函数。

一般实现中,Bp端会注册linkToDeath,目的是为了监听绑定的Service的异常退出,一般的binderDied函数的实现是用来释放一些相关的资源。

public abstract booleanunlinkToDeath (IBinder.DeathRecipient recipient, int flags)

Remove a previously registered death notification. The recipient will no longer be called if this object dies.

可以在Server端(我写的程序中Server端是个一直在系统中运行的Service)中按照如下方式实现DeathHandler,然后在应用程序部分调用notifyProcessDied(new Binder())就可以了。

附Server端的DeathHandler实现。

public boolean notifyProcessDied(IBinder cb){

MyServiceDeathHandler deathHandler = new MyServiceDeathHandler(cb);

try {

cb.linkToDeath(deathHandler, 0);

} catch (RemoteException e) {

return false;

}

return true;

}

private class MyServiceDeathHandler implements IBinder.DeathRecipient {

private IBinder mCb;

public MyServiceDeathHandler(IBinder Cb) {

mCb = Cb;

}

@Override

public void binderDied() {

// release resource when host process died.

}

public IBinder getBinder() {

return mCb;

}

}

至于unlinkToDeath()方法的使用我这边并没有举例具体可以参考AudioManager和AudioService的实现。

其中AudioService是一个Server端,每个程序都有一个AudioManager,AudioManage是一个Client端。

由于应用程序进程被杀死的时候,AudioService需要释放一些资源。所以使用了IBinder的linkToDeath机制来释放一些资源。

Android 11 (API level 30) 中,AIDL (Android Interface Definition Language) 是一种跨进程通信机制,通常用于创建服务之间的接口。如果你正在使用C++作为后端语言,并通过AIDL与Java交互,`waitForService()` 是客户端等待服务可用的一种方式。 首先,你需要在Java端声明一个AIDL服务接口,然后在C++后端实现这个接口。这里是一个简单的示例: **Java端(ServiceInterface.aidl):** ```java interface ServiceInterface { // 这是一个简单的方法声明 String doSomething(String input); } ``` **C++后端(Service.cpp):** ```cpp // 客户端等待服务可用 status_t waitForService() { sp<ServiceInterface> service = new RemoteCallbackList<ServiceInterface>::Callback(); status_t status = service->linkToDeath(service, IBinder::DEATHRecipient::unlinkOn_death); if (status != NO_ERROR) { ALOGE("Failed to link death recipient"); return status; } // 使用AIDL binder注册服务请求 status = client_->connect(service); if (status == NO_ERROR) { // 等待服务注册 status = service->waitForConnectionTimeout(5000); // 设置超时时间(单位ms) if (status == NO_ERROR) { // 服务已连接,可以调用方法了 service->onTransact(0 /* 唯一操作ID */, data, reply, flags); } else { ALOGW("Failed to connect to service within timeout"); } } else { ALOGW("Failed to connect to service"); } return status; } // 调用服务方法 void callDoSomething(const string& input) { Parcel data, reply; data.writeString(input); status_t status = service->transact(0, data, &reply, 0); if (status == NO_ERROR) { string output(reply.readString()); // 输出结果 ALOGI("Response from service: %s", output.c_str()); } else { ALOGE("Failed to invoke method on service"); } } ``` 在这个例子中,`waitForService()` 函数会阻塞直到服务可用并返回一个链接句柄。然后你可以通过这个句柄调用`callDoSomething()` 来实际调用服务的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值