Binder使用

自定义Native层Binder服务

实现Client调用Service的 int add(int x,int y),x,y由Client提供。
参考 binder使用

  • ClientDemo.cpp: 客户端程序
  • ServerDemo.cpp:服务端程序
  • IMyService.h:自定义的MyService服务的头文件
  • IMyService.cpp:自定义的MyService服务
  • Android.mk:源码build文件

实现framework层binder server ,使用aidl编写接口类,实现native层对应的binder client端

  • 首先,在java层注册一个binder server

1 编写aidl文件
在/home/android/frameworks/base/core/java/android/os/ITestService.aidl源码目录下新建ITestService.aidl文件。

 package android.os;
interface ITestService 
{
    int add(int x , int y); //业务函数
}

aidl文件会被自动编译成对应的ITestService.java接口文件

2 修改Adnroid.mk文件,编译aidl文件
修改/home/android/frameworks/base/Android.mk文件
在** LOCAL_SRC_FILES += \ ** 的结尾加上
core/java/android/os/ITestService.aidl
也就是刚刚编写的aidl文件的文件地址
在编译的时候,接口文件会输出到 /home/android/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/ITestService.java
其中只有 add()方法需要实现,节省了大量工作

3 编写java层的service
新建
/home/android/frameworks/base/services/java/com/android/server/TestService.java

package com.android.server;
import android.os.ITestService;

public class TestService extends ITestService.Stub{


    public TestService() {
        super();
       System.out.println("[snake_xing_TestService.java]================init TestService");
    }

    public int add(int x,int y) {
        int sum = x+y;
        System.out.println("[snake_xing_TestService.java]================call add() ");
        return sum;
    }

}

4 在 /home/android/frameworks/base/services/java/com/android/server/SystemServer.java中添加服务
在startOtherServices()函数中

      TestService testService = null; /*Myservice*/
            /*MyService*/
            Slog.i("snake_xing_SystemServer===========", "addMyservice");
            testService = new TestService();
            ServiceManager.addService("mytestservice", testService);  
            /*end*/

仿照telephonyRegistry这个服务添加即可。

build源码(system)
5 进入adb shell ** 检查服务 **是否启动

snake@snakepc:~$ adb shell
root@ASUS_Z00L_93:/ # service list | grep my
0 mytestservice1: [android.os.ITestService1]
** 72 mytestservice: [android.os.ITestService] //这个就是刚刚add的service **
root@ASUS_Z00L_93:/ #

6 修改本地Binder代码

Client端

sp < IBinder > binder = sm->getService(String16("mytestservice"));
改为自己定义的服务名字

IMyService.cpp

IMPLEMENT_META_INTERFACE(MyService, "android.os.ITestService");

name 要改为生成的/home/android/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/ITestService.java
里面定义的 DESCRIPTOR
private static final java.lang.String DESCRIPTOR = "android.os.ITestService";

在ITestService.java文件中,也就是生层的接口文件中的

ITestService.java中的onTransact函数如下:

@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_add:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();    //读出第一个数字
int _arg1;
_arg1 = data.readInt();    //读出第二个数字
int _result = this.add(_arg0, _arg1);  //计算和
reply.writeNoException();    //写入数字noexception也就是0
reply.writeInt(_result);         //写入x+y 的值
return true;
}
}
return super.onTransact(code, data, reply, flags);
}

所以在 BpMyService::add 中 reply.readInt32(); 两次就好

    int BpMyService::add(int a,int b) {
        printf("BpMyService::add\n");
        Parcel data,reply;
        data.writeInterfaceToken(IMyService::getInterfaceDescriptor());
        data.writeInt32(a);
        data.writeInt32(b);
        remote()->transact(HELLO, data, &reply);
        reply.readInt32();           //这里读到的是 0 表示返回正确
        int sum = reply.readInt32();   //这里读到的才是 a+b的和 
        printf("get num from service: %d + %d  = %d \n",a,b,sum);
        return sum;
    }

接下来运行Client

root@ASUS_Z00L_93:/ # ./system/bin/ClientDemo
BpMyService::add
get num from service: 12 + 10 = 22
the sum is : 22
root@ASUS_Z00L_93:/ #

native Binder客户端代码

ClientDemo.cpp: 客户端程序:

#include "IMyService.h"

int main() {
    sp < IServiceManager > sm = defaultServiceManager();
    sp < IBinder > binder = sm->getService(String16("mytestservice"));
    if (binder == NULL)
    {
        printf("binder is NULL\n");
    }
    sp cs = interface_cast < IMyService > (binder);
    if (cs == NULL)
    {
        printf("cs is NULL\n");
    }
    int sum = cs->add(12,10);
    printf("the sum is : %d\n",sum);
    return 0;
}

MyService.h:自定义的MyService服务的头文件

#ifndef MY_SERVICE_DEMO
#define MY_SERVICE_DEMO
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace android;
namespace android
{
    class IMyService : public IInterface
    {
    public:
        DECLARE_META_INTERFACE(MyService); 
        virtual int add(int a,int b)=0; 
    };
    enum
    {
        HELLO = 1,
    };
    class BpMyService: public BpInterface {
    public:
        BpMyService(const sp& impl);
        virtual int add(int a,int b);
    };    
}
#endif


IMyService.cpp:自定义的MyService服务

#include "IMyService.h"
namespace android
{
    IMPLEMENT_META_INTERFACE(MyService, "android.os.ITestService"); 
   
  
    BpMyService::BpMyService(const sp& impl) :
            BpInterface(impl) {
    }
    int BpMyService::add(int a,int b) {
        printf("BpMyService::add\n");
        Parcel data,reply;
        data.writeInterfaceToken(IMyService::getInterfaceDescriptor());
        data.writeInt32(a);
        data.writeInt32(b);
        remote()->transact(HELLO, data, &reply);
        reply.readInt32();
        int sum = reply.readInt32();
        printf("get num from service: %d + %d  = %d \n",a,b,sum);
        return sum;
    }
}

Android.mk:源码build文件

LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := \
    libcutils \
    libutils \
    libbinder
LOCAL_MODULE    := ClientDemo
LOCAL_SRC_FILES := \
    IMyService.cpp \
    ClientDemo.cpp
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)

你可能感兴趣的:(Binder使用)