抱歉,如果这是一个愚蠢的问题。我对 Android 很陌生。
我编写了一个库,该库使用了使用活页夹服务的库。也就是说,我的库有一个派生自使用活页夹的库类的类。
我的库旨在通过 API 以独立于平台的方式提供该数据(它不能公开活页夹依赖项)。对于本次讨论,假设它具有“启动”和“停止”功能。如果引用计数为零,则启动将启动服务,并增加引用计数。 Stop 会减少引用计数,当引用计数变为零时,我想关闭所有内容,运行清理代码等。
我能找到的所有文档都说我必须调用
startThreadPool
和 joinThreadPool
来接收活页夹事件。但是 startThreadPool
会阻塞,因此 Start 函数永远不会返回。
这意味着活页夹订阅需要在线程中进行。但即使我将对
joinThreadPool
的调用放在它自己的线程中,我也不知道如何使 joinThreadPool
干净地退出,以便我可以清理。
所以我尝试创建一个线程,只调用
startThreadPool
并在设置原子时在睡眠循环中旋转;停止清除原子。这在理论上是有效的,但我的调试似乎表明,如果我尝试结束正在使用 API 的进程,我会在执行清理代码之前收到“binder exited”事件。
基本问题是:如何以非阻塞的方式使用binder,然后留下binder并清理?
在这里回答我翻译成英文 https://blog.csdn.net/gaosiniquanjia/article/details/123659277
网上有很多说法,最后一个调用似乎多余;原因是去掉后可以正常执行;但事实并非如此。
我认为;在主线程中调用IPCThread::self()->joinThreadPool()的目的是保证前面调用产生的线程不会因为执行到main函数末尾而被迫退出;因为ProcessState::self()->startThreadPool()不会导致主线程阻塞;和 IPCThread::self()->joinThreadPool() 调用会导致主线程阻塞,并且它们提供相同的功能;它可以处理Binder驱动发送的一些请求或者返回值;进一步提高Binder命令处理的吞吐量。 当然;如果在它们之间添加阻塞主线程的代码,则可以省略最后一个函数调用;否则不能省略。
示例代码:
static pthread_mutex_t s_work_lock;
static pthread_cond_t s_work_cond;
status_t AddBindService::onTransact(uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags)
{
status_t rv(0);
// Perform the requested operation
switch (code) {
case BINDER_EXIT:
cout << "server BINDER_EXIT called" << endl;
reply->writeInt32(0); //before ending signal
pthread_cond_signal(&s_work_cond);
break;
default:
cout << "server onTransact unknown code, code: " << code << endl;
break;
}
return rv;
}
void main()
{
String16 serviceName_server("test.binder_tmp_server"); //register token name
pthread_mutex_init(&s_work_lock, NULL);
pthread_cond_init(&s_work_cond, NULL);
// Add the service
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
if ((rv = sm->addService(serviceName_server, new AddBindService())) != 0) {
cerr << "addService " << serviceName_server << " failed, rv: " << rv << " errno: " << errno << endl;
}
// Start threads to handle server work
proc->startThreadPool();
/*...........your code here*/
//wait signal to exit
pthread_mutex_lock(&s_work_lock);
pthread_cond_wait(&s_work_cond, &s_work_lock);
pthread_mutex_unlock(&s_work_lock);
pthread_cond_destroy(&s_work_cond);
pthread_mutex_destroy(&s_work_lock);
}
参考: