添加native service
-
Native Service 其实就是一个 linux 守护进程,提供一些服务,不过由于 android 的进程间通讯使用了 Binder 机制,那么我们就需要按照 android 的规则来实现我们的 Native Service。
-
客户端在请求 service 的服务时使用了一个具有相同接口的 Proxy 类。native service 这具体实现这个接口,所以 android 提供了 IInterface 类,其是”base class for Binder interfaces”,所以我们的 IZxTask 类继承它:
class IZxTask : public IInterface {
public:
enum { TASK_GET_PID = IBinder::FIRST_CALL_TRANSACTION,
}; virtual int getPid() = 0; DECLARE_META_INTERFACE(ZxTask);
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
IMPLEMENT_META_INTERFACE(ZxTask, "android.hardware.IZxTask");- 1
必须以 I 开头,因为后面会用到一些宏,比如 DECLARE_META_INTERFACE,I 开头是写到宏里面的,所以我们只要传入了 ZxTask 就行了。我们的 Native Service 提供一个接口就是返回 Service 的进程号。
下面我们就需要开始分化实现,一个是客户端,一个是 native service。
先来看代理类class BpZxTask : public BpInterface<IZxTask> {
public:
BpZxTask(const sp<IBinder>& binder)
: BpInterface<IZxTask>(binder)
{
} virtual int getPid()
{
Parcel data, reply;
data.writeInterfaceToken(IZxTask::getInterfaceDescriptor());
remote()->transact(TASK_GET_PID, data, &reply);
return reply.readInt32();
}
};- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
BpInterface 模板类,其中的 p 就是代理的意思。其以我们前面定义的 Interface 为模板参数。
BpInterface 声明如下:template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
BpInterface(const sp<IBinder>& remote); protected:
virtual IBinder* onAsBinder();
};- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
我们的 BpZxTask 需要实现我们定义的接口类中的接口函数。在实现中,我们是客户端,我们需要向 native service 提申请,我们使用 remote 获得关联 service 的 IBinder 对象,然后通过 transact 提交,通过 reply 获得返回值。
下面来看 BnInterface 的实现。
class BnZxTask : public BnInterface<IZxTask> {
public:
virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
};
- 1
- 2
- 3
- 4
- 5
status_t BnZxTask::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{ switch (code) {
case TASK_GET_PID: {
CHECK_INTERFACE(IZxTask, data, reply);
int32_t pid = getPid();
reply->writeInt32(pid);
return NO_ERROR; } break; default:
return BBinder::onTransact(code, data, reply, flags);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
我们在 bpinterface 的 transact 调用会回调 bninterface 的 onTransact 来处理,我们根据 code 参数来进行请求的区分。
BnInterface 类模板其声明如下:
template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
virtual sp<IInterface>
queryLocalInterface(const String16& _descriptor);
virtual const String16& getInterfaceDescriptor() const; protected:
virtual IBinder* onAsBinder();
};- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
其一个父类是继承自 IInterface 的接口类,一个是代表 Binder service 服务端的 BBinder 类。
下面来实现 native service。
class ZxTaskService : public BinderService<ZxTaskService>, public BnZxTask {
public:
virtual int getPid();
static char const* getServiceName() { return "ZxTask"; }
friend class BinderService<ZxTaskService>;
}; int ZxTaskService::getPid()
{
return getpid();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
我们在此实现服务提供的 getPid 接口就 ok,BinderService 模板为我们启动一个 Service 实现了逻辑封装。
BinderService 实现如下:template<typename SERVICE>
class BinderService
{
public:
static status_t publish(bool allowIsolated = false) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(
String16(SERVICE::getServiceName()),
new SERVICE(), allowIsolated);
} static void publishAndJoinThreadPool(bool allowIsolated = false) {
publish(allowIsolated);
joinThreadPool();
} static void instantiate() { publish(); } static status_t shutdown() { return NO_ERROR; } private:
static void joinThreadPool() {
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
ps->giveThreadPoolName();
IPCThreadState::self()->joinThreadPool();
}
};- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
其要求模板参数实现
getServiceName方法,publish和publishAndJoinThreadPool函数实现了该
service 添加到 SM 的逻辑,publish 只是 add,而publishAndJoinThreadPool会启动该
service。这里我们就完成了 native service 的开发,我们将其编成库。
Android.mkLOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := \
ZxTask.cpp \
ZxTaskService.cpp LOCAL_C_INCLUDES := \
system/core/include \
frameworks/native/include LOCAL_SHARED_LIBRARIES := \
libbinder \
libutils \ LOCAL_MODULE:= libzxtask include $(BUILD_SHARED_LIBRARY)- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
我们写一个 service 的可执行程序。
main.cpp#include "service/ZxTaskService.h" int main()
{
/* code */
android::ZxTaskService::publishAndJoinThreadPool();
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Android.mk
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := \
main.cpp \ LOCAL_C_INCLUDES := frameworks/base/zxTask LOCAL_MODULE:= zxtaskservice LOCAL_SHARED_LIBRARIES := libzxtask libutils libbinder include $(BUILD_EXECUTABLE)- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
写一个测试客户端
main.cpp
#include "service/ZxTask.h"
#include <binder/IServiceManager.h>
#include <unistd.h>
#include <stdio.h> int main()
{
using namespace android;
sp<IServiceManager> sm =defaultServiceManager();
printf("%s\n", "get serviceManager");
sp<IBinder> binder =sm->getService(String16("ZxTask"));
sp<IZxTask> mTask =interface_cast<IZxTask>(binder);
printf("ZxTask Service pid %d, client pid:%d",mTask->getPid(), getpid()); return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
Android.mk
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := \
main.cpp \ LOCAL_C_INCLUDES := frameworks/base/zxTask LOCAL_MODULE:= zxtaskclient LOCAL_SHARED_LIBRARIES := libzxtask libutils libbinder include $(BUILD_EXECUTABLE)- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
其中用到了
interface_cast。template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}- 1
- 2
- 3
- 4
- 5
其使用了 asInterface 函数,而这个函数就是我们在 IZxTask 里面使用
DECLARE_META_INTERFACE声明的。#define DECLARE_META_INTERFACE(INTERFACE) \
static const android::String16 descriptor; \
static android::sp<I##INTERFACE> asInterface( \
const android::sp<android::IBinder>& obj); \
virtual const android::String16& getInterfaceDescriptor() const;\
I##INTERFACE(); \
virtual ~I##INTERFACE();- 1
- 2
- 3
- 4
- 5
- 6
- 7
其声明了一个描述的类属性,我们使用的
asInterface函数。
看下IMPLEMENT_META_INTERFACE宏。#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
const android::String16 I##INTERFACE::descriptor(NAME); \
const android::String16& \
I##INTERFACE::getInterfaceDescriptor() const { \
return I##INTERFACE::descriptor; \
} \
android::sp<I##INTERFACE> I##INTERFACE::asInterface( \
const android::sp<android::IBinder>& obj) \
{ \
android::sp<I##INTERFACE> intr; \
if (obj != NULL) { \
intr = static_cast<I##INTERFACE*>( \
obj->queryLocalInterface( \
I##INTERFACE::descriptor).get()); \
if (intr == NULL) { \
intr = new Bp##INTERFACE(obj); \
} \
} \
return intr; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { } \- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
主要看
asInterface的实现。其会调用 IBinder 的 queryLocalInterface
查询我们的接口对象,这里使用了基类指针,如果没有就 new 出来。我们的 BpZxTask 只有在这个函数中使用,这也是为什么我在实现时,指示全部把它放在了 cpp 文件中。intr = new Bp##INTERFACE(obj);- 1
这一句表明我们的 Proxy 类一定以 Bp 开头且 IBinder 对象作为构造的参数传入,实现了 proxy 和 IBinder 对象的绑定。
sp<IBinder> binder =sm->getService(String16("ZxTask"));- 1
根据 service 名获得这个 service 的 IBinder 对象,使用
interface_cast实现了客户端的
Proxy 和 service 的 IBinder 的绑定,然后我们在 getPid 中就可以调用 IBinder 的 transact 函数,这样就和 remote 通讯上,回调到 native service 的 onTransact 的接口,然后处理了将结果返回,这样就实现了 client 和 service 的通讯。运行如下图:
添加native service的更多相关文章
- 王家林的81门一站式云计算分布式大数据&移动互联网解决方案课程第14门课程:Android软硬整合设计与框架揭秘: HAL&Framework &Native Service &App&HTML5架构设计与实战开发
掌握Android从底层开发到框架整合技术到上层App开发及HTML5的全部技术: 一次彻底的Android架构.思想和实战技术的洗礼: 彻底掌握Andorid HAL.Android Runtime ...
- 你会在C#的类库中添加web service引用吗?
本文并不是什么高深的文章,只是VS2008应用中的一小部分,但小部分你不一定会,要不你试试: 本人对于分布式开发应用的并不多,这次正好有一个项目要应用web service,我的开发环境是vs2008 ...
- 11、四大组件之二-Service高级(二)Native Service
一.Service的分类 1.1>Android Service 使用Java编写在JVM中运行的服务 1.2>Native Service 使用C/C++完成的服务,一般在系统开始时完成 ...
- Binder机制,从Java到C (7. Native Service)
1.什么是NativeService Native Service,是通过C或C++代码写出來,提供给Java进行远程调用的RemoteService.向Android开机就启动的surfacefli ...
- C#:添加web service引用
VS2012里是这样添加web service引用的:
- VS2010下创建WEBSERVICE,第二天 ----你会在C#的类库中添加web service引用吗?
本文并不是什么高深的文章,只是VS2008应用中的一小部分,但小部分你不一定会,要不你试试: 本人对于分布式开发应用的并不多,这次正好有一个项目要应用web service,我的开发环境是vs2008 ...
- xxx.service is not a native service, redirecting to /sbin/chkconfig.
centos7编译安装的程序无法用systemctl 启动 [root@nagios-server check_commands]# systemctl enable npcd.service npc ...
- 从零開始怎么写android native service?
从零開始怎么写android native service Android service对于从事android开发的人都不是一个陌生的东西,非常多人可能会认为服务非常easy. 服务是简单,由于复杂 ...
- NRF52840 添加 led service
记录NRF52840 添加LED service的流程,以及遇到的问题. 由于SDK中已经有了led service的.c和.h文件,因此只需要添加文件,并且调用相关函数即可. 注:编译调试环境为ke ...
随机推荐
- CSS3制作动画的三个属性
CSS3属性中有关于制作动画的三个属性:Transform,Transition,Animation:我们一起学习完了Transform和Transition,让我们对元素实现了一些基本的动画效果,这 ...
- iOS-钥匙串中证书全部失效(证书的签发者无效)的解决办法
今天用Xcode打包IPA文件给同事,结果提示import时,提示证书missing,找了半天没发现问题,后来打开钥匙串,发现证书全失效了!!!根证书失效了!吓死宝宝了 解决方法 首选此方法: 1.打 ...
- IT从业者的职业道路(从程序员到部门经理) - 项目管理系列文章
十年前,笔者还是一个刚毕业的大学生,对IT业只是停留在学校的编程知识领域.刚出社会,有很多需要学习的地方.在这十年间,笔者经历了程序员,技术经理,项目经理,部门经理等职位.本文就是要说说如何从程序员到 ...
- Symantec Backup Exec 2012 Agent For Linux安装
Backup Exec 2012 介绍 Backup Exec 2012 是一种为虚拟和物理环境提供保护的集成产品,能够简化备份和灾难恢复,并提供了无可匹敌的恢复功能.借助于强大的 Symantec ...
- Database 'xxxx' is being recovered. Waiting until recovery is finished.
巡检发现一个SQL SERVER Express 2005数据库备份时出现下面错误: Database 'xxxx' is being recovered. Waiting until recover ...
- SQL SERVER 重组含有特殊字符的索引时遇到“关键字 'with' 附近有语法错误.”
案例描述 这是在索引重组过程中遇到的有意思的错误案例,搜索了一下也没有看到相关资料,估计我第一个碰到这类错误的人(It's just a joke).具体情况是YourSQLDba在做维护数据库索引时 ...
- 解决session阻塞的问题
简介 对于数据库运维人员来说创建session或者查询时产生问题是常规情况,下面介绍一种很有效且不借助第三方工具的方式来解决类似问题. 最近开始接触运维工作,所以自己总结一些方案便于不懂数据库的同事解 ...
- JAVA之直接内存(DirectMemory)
Baisics: JAVA NIO使用,基于通道和缓冲区的IO方式,使用Native函数库直接分配堆外内存(allocateDirect),然后通过一个Java堆中的DirectByteBuffer对 ...
- 优化mysql服务器
一.使用show variables 和show status 命令查看MySQL的服务器静态参数值和动态运行状态信息. 二.可以使用 mysqld --verbose --help|more 查看某 ...
- W3School-CSS 内边距 (padding) 实例
CSS 内边距 (padding) 实例 CSS 实例 CSS 背景实例 CSS 文本实例 CSS 字体(font)实例 CSS 边框(border)实例 CSS 外边距 (margin) 实例 CS ...