Android下在C++环境实现native层binder服务
来源:互联网 发布:mac窗口缩小快捷键 编辑:程序博客网 时间:2024/06/05 03:30
此文章主要目的:在Android 6.0 arm 64位环境下使用C++编程实现binder通讯服务端和客户端
即native层binder服务通讯实现
此例子同时实现了int和string数据通讯接口
程序框架图
1.在Android源码目录下存放代码树形结构
development目录下创建相关文件列表
jack_server/
├── Android.mk
├── log.h
├── service
│ ├── Android.mk
│ ├── JACK_Service.cpp
│ └── JACK_Service.h
├── svcclient
│ ├── Android.mk
│ ├── JACK_Client.cpp
│ └── JACK_Client.h
├── svcserver
│ ├── Android.mk
│ └── JACK_server.cpp
└── svctest
├── Android.mk
└── test.cpp
2.首先实现服务端
创建目录service 再创建如下三个文件
JACK_Service.h
#ifndef ANDROID_JACK_SERVICE_H#define ANDROID_JACK_SERVICE_H#include <utils/RefBase.h>#include <binder/IInterface.h>#include <binder/Parcel.h>namespace android{ class JACK_Service : public BBinder { private: //mutable Mutex m_Lock; //int32_t m_NextConnId; public: static int Instance(); JACK_Service(); virtual ~JACK_Service(); virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t); };}#endif
JACK_Service.cpp
#include <binder/IServiceManager.h>#include <binder/IPCThreadState.h>#include "JACK_Service.h"#include "../log.h"namespace android{ //static struct sigaction oldact; static pthread_key_t sigbuskey; int JACK_Service::Instance() { DebugPrint("JACK_Service Instantiate\n"); int ret = defaultServiceManager()->addService( String16("jack.svc"), new JACK_Service()); DebugPrint(" JACK_Service ret = %d\n", ret); return ret; } JACK_Service::JACK_Service() { DebugPrint(" JACK_Service create\n"); //m_NextConnId = 1; pthread_key_create(&sigbuskey,NULL); } JACK_Service::~JACK_Service() { pthread_key_delete(sigbuskey); DebugPrint(" JACK_Service destory\n"); } status_t JACK_Service::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case 0: { pid_t pid = data.readInt32(); int num = data.readInt32(); num += 1000; reply->writeInt32(num); return NO_ERROR; } break;case 1: { pid_t pid = data.readInt32(); String8 str = data.readString8();DebugPrint(" case 1 = %s \n",str.string());String8 add_str = String8("jack_service get ")+str; //str = add_str + str; reply->writeString8(add_str); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } }}Android.mk
LOCAL_PATH:=$(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:=JACK_Service.cppLOCAL_SHARED_LIBRARIES:=libutils libbinderLOCAL_MODULE_TAGS:=optionalLOCAL_MODULE:=libJACK_ServiceLOCAL_PRELINK_MODULE:=falseinclude $(BUILD_SHARED_LIBRARY)
3.接下来就是启动服务端的应用程序
创建目录svcserver 再创建如下文件
JACK_server.cpp
#include <stdio.h>#include <sys/types.h>#include <unistd.h>#include <grp.h>#include <binder/IPCThreadState.h>#include <binder/ProcessState.h>#include <binder/IServiceManager.h>#include <utils/Log.h>#include "../service/JACK_Service.h"#include "../log.h"using namespace android;int main(int arg, char** argv){ DebugPrint(" server - ain() begin\n"); sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm = defaultServiceManager(); //LOGI("ServiceManager: %p\n", sm.get()); DebugPrint(" server - erviceManager: %p\n", sm.get()); int ret = JACK_Service::Instance(); DebugPrint(" server - JACK_Service::Instance return %d\n", ret); ProcessState::self()->startThreadPool();IPCThreadState::self()->joinThreadPool();return 0;}
Android.mk
LOCAL_PATH:=$(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:=JACK_server.cppLOCAL_SHARED_LIBRARIES:=libutils libbinder libJACK_ServiceLOCAL_MODULE_TAGS:=optionalLOCAL_MODULE:=JACK_serverinclude $(BUILD_EXECUTABLE)
当前目录执行mm即可生成out目录/system/bin/下 JACK_server可执行bin文件,在开发板上直接执行即可启动binder服务端
ps进程列表可以看到相关进程
4.客户端的实现
创建目录svcclient再创建相关文件
JACK_Client.h
#ifndef ANDROID_JACK_CLIENT_H#define ANDROID_JACK_CLIENT_H#include <binder/Parcel.h>namespace android{ class JACK_Client { public: int setN(int n);String8 setString8(String8 str); private: static void getJACK_Service(); };}#endif
JACK_Client.cpp
#include <binder/IServiceManager.h>#include <binder/IPCThreadState.h>#include "JACK_Client.h"#include "../log.h"#include<android/log.h> namespace android{ sp<IBinder> binder; int JACK_Client::setN(int n) { getJACK_Service(); Parcel data, reply; data.writeInt32(getpid()); data.writeInt32(n); DebugPrint(" client - binder->transact()\n"); binder->transact(0, data, &reply); int r = reply.readInt32(); return r; } String8 JACK_Client::setString8(String8 str) { getJACK_Service(); Parcel data, reply;//获取或创建Parcel对象 data.writeInt32(getpid());//写入Parcel数据 data.writeString8(str); //ALOGE("chyj send %s",str.string()); DebugPrint(" client - binder->transact() send %s \n",str.string()); binder->transact(1, data, &reply);//通过Binder传递数据 1是函数顺序号,必须对应 String8 r = reply.readString8();//reply接收数据DebugPrint(" setString8 reply %s \n",r.string());//ALOGE("chyj reply %s",r.string()); return r; } void JACK_Client::getJACK_Service() { sp<IServiceManager> sm = defaultServiceManager(); binder = sm->getService(String16("jack.svc")); DebugPrint(" client - etService: %p\n", sm.get()); if(binder == 0) { DebugPrint(" JACK_Service not published, waiting..."); return; } }}
Android.mk
LOCAL_PATH:=$(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:=JACK_Client.cppLOCAL_SHARED_LIBRARIES:=libutils libbinder LOCAL_LDLIBS := -lm -llog #解决undefined reference to `__android_log_print'LOCAL_MODULE_TAGS:=optionalLOCAL_MODULE:=libJACK_ClientLOCAL_PRELINK_MODULE:=falseinclude $(BUILD_SHARED_LIBRARY)
5.客户端的应用程序实现
创建目录svctest和相关文件
test.cpp
#include <stdio.h>#include "../svcclient/JACK_Client.h"#include "../log.h"#include <utils/String8.h>using namespace android;int main(int argc, char** argv){ JACK_Client client;DebugPrint(" start test"); int ret = client.setN(2017); DebugPrint("setN return: %d\n", ret);String8 send = String8("hello I'm string");String8 str = client.setString8(send);DebugPrint("setString8 return: %s\n",str.string());//ALOGE("chyj setString8 return %s",str.string()); return 0;}
Android.mk
LOCAL_PATH:=$(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:=test.cppLOCAL_SHARED_LIBRARIES:=libJACK_Client libutilsLOCAL_LDLIBS := -lm -llog #解决undefined reference to `__android_log_print'LOCAL_MODULE_TAGS:=optionalLOCAL_MODULE:=JACK_svctestinclude $(BUILD_EXECUTABLE)
当前目录mm生成out目录/system/bin/下JACK_svctest,在板子上执行可执行文件即可和服务端实现通讯
6.最后是整体编译的文件
在最外层目录jack_server创建
log.h用于打印控制调试用
log.h
#define __DEBUG__ #define TAG "chyj" #ifdef __DEBUG__ //改进方法#define DebugPrint(fmt,args...) printf("[file:%s fun:%s line:%d tag:%s]: " fmt "\n", __FILE__, __FUNCTION__, __LINE__, TAG, ##args);#else#define DebugPrint(fmt,args...) #endif
Android.mk
include $(call all-subdir-makefiles)
如果希望开机启动binder服务
可以在init.rc下实现service
service JACK_server /system/bin/JACK_server class main oneshot
- Android下在C++环境实现native层binder服务
- Android中实现native服务利用binder与应用通信
- android Binder机制3---Native层
- Binder(native层)
- Android------Binder java层如何与native层交互
- c++ 层实现binder服务例子
- Java层的Binder服务实现
- Android服务Binder实现小记
- android libbinder – Binder的Native实现
- Android系统的Binder机制及其native层应用
- 在Android Native层直接调用MediaCodec接口的实现
- Binder机制3---Native层
- Binder机制3---Native层
- Binder机制3---Native层
- android binder机制,注册系统服务---native客户端
- Android Native层Binder.transact()函数调用 Binder.onTransact() 函数失败分析
- Android Native Binder
- Android Binder Native
- Java 线程 Executor 框架详解与使用
- Iaas PaaS Saas总结
- HttpClient获取重定向之后的网址信息
- java.util.Date和java.sql.Date的区别和相互转化
- 仿美团项目学习源码分析(3)--数组加key
- Android下在C++环境实现native层binder服务
- LOCAL_STATIC_LIBRARIES引用先后顺序问题
- 最新 chrome下载 [不定更新]
- 第六章——树和二叉树
- 动态修改AlearDialog 中的按钮 和不允许点击按钮关闭窗口
- 0_
- 欢迎使用CSDN-markdown编辑器
- maven中去掉单元测试的配置
- HDU1014