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/
浙公网安备 33010602011771号