Jimmy Chen

A Programmer

(原创)在Native层使用Binder创建服务

  要编写Native层的binder服务,其实大家可以参考Android系统中带有的服务进行编写,这里主要讲流程,原理性的东西大家可以参考博主之前的文章。另外我们这里编写的服务程序只是简单的提供加减乘除运算的,不做特别难的事情。

流程

在着手编写native层binder服务前,我们先整理一下Binder调用的整个流程

Client调用Service

  client要调用Service的功能,首先需要获取到一个BpXXXXXService对象,然后就可以直接调用BpXXXXXService类中定义的方法,在这些方法中,并不会执行真正的操作,而是包装好数据后再调用remote()->transact方法将这些数据发送出去。这里的remote()方法是在BpRefBase中实现的,remote()方法返回的就是一个BpBinder对象,所以其实这里调用的就是BpBinder的transact方法。

service处理请求

  client的数据发送出去之后,service通过IPCThreadState接收到client的请求后,会调用BBinder的transact方法,BBInder的transact方法再调用其子类BnXXXXXService中实现的onTransact方法。onTransact方法会根据传进来的code调用到实际XXXXXService中的方法,进行实际的操作,然后再将返回值返回给onTransact,onTransact将结果写入到reply里面返回给BpXXXXXService,这样就完成了一轮操作。

IArithmeticService.h

  我的目录结构如下,创建一个名为arithmetic的文件夹,文件夹内再创建一个include文件夹,include文件夹内创建一个IArithmeticService.h文件,然后再arithmetic文件夹中创建Android.mk、ArithmeticService.cpp、ArithmeticService.h和IArithmeticService.cpp这四个文件。下面开始编写代码。

  首先创建一个IArithmeticService类,这个类作为BpArithmeticService和BnArithmeticService的父类存在,我们在这里定义实际需要完成的Binder工作函数,同时定义出BnArithmeticService类,代码如下:

IArithmeticService.cpp

在这个文件中,需要完成BpArithmeticService和BnArithmeticService类的实际编写。

ArithmeticService.h

这里就是实际的Service类,从BnXXXXXService类中继承而来。

ArithmeticService.cpp

最终的Service文件

添加启动代码

  首先在framework/av/media/mediaserver/Android.mk中的LOCAL_C_INCLUDES中添加如下一行: framework/arithmetic/ \ 记得最后还要加上‘\’反斜杠;在LOCAL_SHARED_LIBYARIES中添加如下一行:libarithmeticservice \ 当然也要记得最后的‘\’反斜杠。

  然后我们模仿MediaPlayerService那样,在main_mediaserver.cpp文件中添加ArithmeticService的启动代码,当然你也可以自己编写一个c程序来启动这个service

Selinux权限

Selinux权限的设置分为三步

(1)首先需要服务起来的时候,服务需要有一个定义的type,所以我们在service.te文件中为我们的service定一个type

(2)为service定义了一个type后,那么就需要将这个type赋予我们的service了,我们在service_contexts中添加如下代码,这样service起来后,它的type就是arithmetic_service了

(3)最后就是添加allow规则,因为闲杂我们的service是在MediaServer中加载起来的,而所以我们在mediaserver.te文件中添加如下allow规则

这样,Selinux权限方面的内容就OK了

编译运行

  然后就是编写相应的Android.mk文件了

  编写完Android.mk文件后,直接将整个arithmetic文件夹放到android源码根目录下的framework文件夹下面编译即可。编译完成后,可以在out/target/product/{Project}/system/lib目录下找到一个名为libarithmeticservice.so的文件。

  然后就是刷机启动了,简单的判断service有没有起来的方法就是手机开机以后使用adb连接手机,然后通过service list指令就可以列出手机当前运行的service,一切都没有问题的话,我们添加的arithmetic服务就运行起来了。

编写client程序

  直接在arithmetic目录下面添加一个ari_client目录,在目录内添加Android.mk和main_client.cpp文件。main_client.cpp文件内容如下:

  Android.mk文件的内容:

  按照原本的目录层次,将更新后的代码放到framework文件夹下面,用mmm编译,就可以在out/target/product/{Project}/system/bin路劲下看到一个arithmeticclient的可执行程序。如果之前编译的是user版本,那么只能执行make刷机了,如果是eng版本的软件可以通过usb插上手机,执行adb remount,然后将这个文件push到手机/system/bin路劲下,然后直接执行就可以了。因为使用的是Android的Log输出,所以要用adb shell logcat ArithmeticClient:D ArithmeticService:D *:s -v threadtime才能看到最后的输出的内容

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注