Binder反向调用和linkToDeath来实现资源清理
Client端:
static sp<ITxDtvService> dtvsrv = NULL; static sp<DtvResClient> client = NULL; class DtvResClient : public BnTxDtvResClient { public: int getClientPid() { return getpid(); } }; tx_status_code_t tx_dtv_system_init(void) { sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> binder; do { binder = sm->getService(String16(TX_DTV_SERVICE_NAME)); if (binder != NULL) break; tx_printf(0, "waiting for dvbserver.....\n"); usleep(300000); //0.3 s } while(true); if (dtvsrv.get()) dtvsrv.clear(); dtvsrv = interface_cast<ITxDtvService>(binder); client = new DtvResClient(); dtvsrv->resourceInit(client); return TX_NO_ERROR; }
|
Server端:
H
class TxDtvService : public BnTxDtvService, public IBinder::DeathRecipient { public: static TxDtvService* instantiate();
bool resourceInit(const sp<ITxDtvResClient>& client); bool resourceTerm(const sp<ITxDtvResClient>& client); void binderDied(const wp<IBinder>& who); private: static TxDtvService* srv; };
|
Cpp:
TxDtvService* TxDtvService::srv = NULL;
TxDtvService* TxDtvService::instantiate() { if (srv) return srv; srv = new TxDtvService(); return srv; }
bool TxDtvService::resourceInit(const sp<ITxDtvResClient>& client) { printf("resourceInit from process pid=%d\n", client->getClientPid()); client->asBinder()->linkToDeath(this); return true; }
bool TxDtvService::resourceTerm(const sp<ITxDtvResClient>& client) { printf("resourceTerm from process pid=%d\n", client->getClientPid()); client->asBinder()->unlinkToDeath(this); return true; }
void TxDtvService::binderDied(const wp<IBinder>& who) { printf("a client died\n"); }
|
class TxDtvService 要继承IBinder::DeathRecipient
client在linkToDeath后,当client端new的client被delete或进程退出后就会调用TxDtvService的成员函数binderDied。
说明:
1.这里是一个反向调用的例子,即server调用client端的函数。前提是client端首先获得server。这样就实现了双向调用的进程间通讯。
2.这里是一个通过server继承DeathRecipient来实现监视client端退出的例子。这样可实现client退出后,server端进行资源的清理工作。同样也可通过同样的方式实现client来监视server是否退出。