android控制台应用binder通讯

在android root环境下,有一个后台服务server进程需要提供接口给控制台应用client调用,本来想用socket方式来做的,后台发现android有更高效的方式来实现.那就是binder.

查了一下资料,具体的binder驱动的实现细节比较复杂,网上一堆教程都是先aidl,再生成代码,

其实不用那么复杂,下面应该是最简单写法了。

 

server

#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <utils/Errors.h>
#include <pthread>

using namespace android;
//客户端回调引用
sp<IBinder> clientCallback;

enum {
    code_test_hello = 1, 
    code_test_callback_registe = 2
}

enum {
    cb_code_test = 1
}

void callback_test(const char* params) {
    if (clientCallback == NULL) { \
        LOGD("%s clientCallback == null", __FUNCTION__); 
        return; 
    }  
    if (!clientCallback->isBinderAlive()){ 
         LOGD("%s clientCallback not alive", __FUNCTION__); 
        return; 
     }
 
    int32_t t =  clientCallback->pingBinder();
    bool b = clientCallback->isBinderAlive();
    Parcel request, reply;
    request.writeCString(params);
    clientCallback->transact(EnumCallback::cb_code_test, request, &reply);
}

class ServiceService: public BBinder {
public:
    ServiceService();
    virtual status_t onTransact(uint32_t code, const Parcel&, Parcel*, uint32_t){
        switch(code) {
        
            case code_test_hello:
            {
                printf("from client:%s", request.readCString());
                reply->writeCString("hello client");
                return NO_ERROR;
            }
            case code_test_callback_registe: 
            {
                clientCallback = request.readStrongBinder();
                reply->writeInt32(0);
                return NO_ERROR;
            }
        }
        
        return BBinder::onTransact(code, request, reply, flag);
    }
};

void *binderThread (void *arg){
    sp<ProcessState> proc(ProcessState::self());
    defaultServiceManager()->addService(String16("ServiceService"), new ServiceService());
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
    return ((void *)0);
}

int initBinderPool() {
    return pthread_create(NULL, NULL, binderThread, NULL);
}

int main(int argc, char *argv[]) {
    //启动binder框架线程池
    initBinderPool();
    while(true) {
        callback_test("hello word");
        sleep(1);
    }
    
    return 0;
}

client

#include <binder/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <utils/Errors.h>
#include <stdio.h>
#include <binder/IMemory.h>
#include <binder/MemoryHeapBase.h>
#include <binder/MemoryBase.h>
#include <android/log.h>

#define TAG "bindertest"
#define LOGD(...) \
printf(__VA_ARGS__); \
__android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)

using namespace android;
static sp<IBinder> service;

enum {
    code_test_hello = 1, 
    code_test_callback_registe = 2
}

enum {
    cb_code_test = 1
}

class Callback : public BBinder {
    public:
    status_t onTransact(uint32_t code, const Parcel &request, Parcel *reply, uint32_t flag) {
        switch (code) {
            case cb_code_test:{
                const char* str = request.readCString();
                LOGD("msg from server cb:%s\n", str);
                reply->writeInt32(0);
                break;
            }
        }

        return BBinder::onTransact(code, request, reply, flag);
    }
};

static void callback_connect(const sp<Callback>& callback) {
    if (service == NULL) { 
        LOGD("[%s] service not init", __FUNCTION__);
        return ret; 
    }

    Parcel request, reply;
    request.writeStrongBinder(callback);
    service->transact(CMD_CALLBACK_INIT, request, &reply);
}


void* binderThread(void* params){
    sp<ProcessState> proc(ProcessState::self());
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
    return NULL;
}


void testHello() {
    if (service == NULL) { 
        LOGD("[%s] service not init", __FUNCTION__);
        return ret; 
    }

    Parcel request, reply;
    request.writeCString("hello server");
    service->transact(code_test_hello, request, &reply);
    printf("from server:%s", reply.readCString());
}

int main(int argc, char *argv[]) {
    sp<ProcessState> proc(ProcessState::self());
    service = defaultServiceManager()->getService(String16("ServiceService"));
    if (!service) {
        LOGD("get ServiceService fail");
        return 0;
    }
    
    //注册回调
    sp<Callback> callback = new Callback();
    callback_connect(callback);
    //启动binder线程池,不启动的话,server端的回调会卡住
    pthread_create(NULL, NULL, binderThread,NULL);

    while(true) {
        testHello();
        sleep(1);
    }
    
    return 0;
}

 

 

参考

http://qiushao.net/2019/12/29/Android%E7%B3%BB%E7%BB%9F%E5%BC%80%E5%8F%91%E5%85%A5%E9%97%A8/9-%E6%B7%BB%E5%8A%A0native%E7%B3%BB%E7%BB%9F%E6%9C%8D%E5%8A%A1/

 

posted on 2022-12-19 14:34  Jamy325  阅读(72)  评论(0)    收藏  举报

导航