Android编程-如何离开binder

问题描述 投票:0回答:1

抱歉,如果这是一个愚蠢的问题。我对 Android 很陌生。

我编写了一个库,该库使用了使用活页夹服务的库。也就是说,我的库有一个派生自使用活页夹的库类的类。

我的库旨在通过 API 以独立于平台的方式提供该数据(它不能公开活页夹依赖项)。对于本次讨论,假设它具有“启动”和“停止”功能。如果引用计数为零,则启动将启动服务,并增加引用计数。 Stop 会减少引用计数,当引用计数变为零时,我想关闭所有内容,运行清理代码等。

我能找到的所有文档都说我必须调用

startThreadPool
joinThreadPool
来接收活页夹事件。但是
startThreadPool
会阻塞,因此 Start 函数永远不会返回。

这意味着活页夹订阅需要在线程中进行。但即使我将对

joinThreadPool
的调用放在它自己的线程中,我也不知道如何使
joinThreadPool
干净地退出,以便我可以清理。

所以我尝试创建一个线程,只调用

startThreadPool
并在设置原子时在睡眠循环中旋转;停止清除原子。这在理论上是有效的,但我的调试似乎表明,如果我尝试结束正在使用 API 的进程,我会在执行清理代码之前收到“binder exited”事件。

基本问题是:如何以非阻塞的方式使用binder,然后留下binder并清理?

android c++ android-binder
1个回答
0
投票

在这里回答我翻译成英文 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);
}

参考:

  1. https://android.googlesource.com/platform/frameworks/native/+/refs/tags/android-9.0.0_r60/services/surfaceflinger/main_surfaceflinger.cpp

  2. https://android.googlesource.com/platform/system/extras/+/refs/tags/android-9.0.0_r60/tests/binder/benchmarks/binderAddInts.cpp

© www.soinside.com 2019 - 2024. All rights reserved.