android有哪些native服务器,Android下在C++环境实现native层binder服务

此文章主要目的:在Android 6.0 arm 64位环境下使用C++编程实现binder通讯服务端和客户端

即native层binder服务通讯实现

此例子同时实现了int和string数据通讯接口

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

程序框架图

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

#include

#include

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

#include

#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.cpp

LOCAL_SHARED_LIBRARIES:=libutils libbinder

LOCAL_MODULE_TAGS:=optional

LOCAL_MODULE:=libJACK_Service

LOCAL_PRELINK_MODULE:=false

include $(BUILD_SHARED_LIBRARY)

即可通过当前目录下mm 生成 out目录/system/lib64/下libJACK_Service.so 服务端

3.接下来就是启动服务端的应用程序

创建目录svcserver 再创建如下文件

JACK_server.cpp

#include

#include

#include

#include

#include

#include

#include

#include

#include "../service/JACK_Service.h"

#include "../log.h"

using namespace android;

int main(int arg, char** argv)

{

DebugPrint(" server - ain() begin\n");

sp proc(ProcessState::self());

sp 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.cpp

LOCAL_SHARED_LIBRARIES:=libutils libbinder libJACK_Service

LOCAL_MODULE_TAGS:=optional

LOCAL_MODULE:=JACK_server

include $(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

namespace android

{

class JACK_Client

{

public:

int setN(int n);

String8 setString8(String8 str);

private:

static void getJACK_Service();

};

}

#endif

JACK_Client.cpp

#include

#include

#include "JACK_Client.h"

#include "../log.h"

#include

namespace android

{

sp 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 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.cpp

LOCAL_SHARED_LIBRARIES:=libutils libbinder

LOCAL_LDLIBS := -lm -llog #解决undefined reference to `__android_log_print'

LOCAL_MODULE_TAGS:=optional

LOCAL_MODULE:=libJACK_Client

LOCAL_PRELINK_MODULE:=false

include $(BUILD_SHARED_LIBRARY)

当前目录mm编译out目录/system/lib64/下生成

libJACK_Client.so

5.客户端的应用程序实现

创建目录svctest和相关文件

test.cpp

#include

#include "../svcclient/JACK_Client.h"

#include "../log.h"

#include

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.cpp

LOCAL_SHARED_LIBRARIES:=libJACK_Client libutils

LOCAL_LDLIBS := -lm -llog #解决undefined reference to `__android_log_print'

LOCAL_MODULE_TAGS:=optional

LOCAL_MODULE:=JACK_svctest

include $(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服务在C++环境通讯访问

如果希望开机启动binder服务

可以在init.rc下实现service

service JACK_server /system/bin/JACK_server

class main

oneshot

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值