Binder service入门—框架层、应用层调用native binder service

转载:http://www.cnblogs.com/herenzhiming/articles/5074487.html
本文原创作者:Cloud Chou.

1.前言

Binder service入门系列:

Binder service入门–创建native binder service:
http://www.cloudchou.com/android/post-332.html
Binder service入门—Framework binder service:
http://www.cloudchou.com/android/post-447.html
Binder service入门—应用层binder service:
http://www.cloudchou.com/android/post-458.html

本篇将综合先前介绍的native binder service,framework binder service,应用层binder service等知识,讲述如何使用native 的client,framework层的client,应用层的client测试native binder service。

2.程序构成
因为编译native的binder service,framework层的client都需要在源码环境下编译,故此本篇讲述的工程需要在源码环境下编译。
整个工程可以在github上下载:
https://github.com/cloudchou/NativeBinderJavaClientDemo

程序由4个部分组成:
1) native_bserver 创建并注册native binder service的本地服务端
2) native_bclient 测试native binder service的本地客户端
3) fclient和fclient.jar测试native binder service的框架层客户端
4) NativeBinderServiceTest 测试native binder service的应用层客户端

3.程序源码构成
源程序目录结构如下所示:
这里写图片描述

顶层Android.mk只是简单包含各个子目录的Android.mk,BServer目录存放本地服务端和本地客户端源码,FClient存放框架层客户端源码,NatviveBinderServiceTest存放应用层客户端源码。
本地服务端和本地客户端

1) BServer的Android.mk源码如下所示:
LOCAL_PATH := $(call my-dir)

#生成binder service的本地服务端
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := \
    libcutils \
    libutils \
    libbinder       
LOCAL_MODULE    := native_bserver
LOCAL_SRC_FILES := \
    ICloudManager.cpp \
    TestServer.cpp   
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)

#生成binder service的本地客户端
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := \
    libcutils \
    libutils \
    libbinder
LOCAL_MODULE    := native_bclient
LOCAL_SRC_FILES := \
    ICloudManager.cpp \
    TestClient.cpp
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)
2) binder service接口ICloudManager(ICloudManager.h):
namespace android
{
    class ICloudManager : public IInterface
    {
    public:
        DECLARE_META_INTERFACE(CloudManager); // declare macro
        virtual void test()=0;
        virtual void print(const char* str)=0;
        virtual int add(int a, int b)=0;
    };

    enum
    {
        TEST = IBinder::FIRST_CALL_TRANSACTION+1,
        PRINT = IBinder::FIRST_CALL_TRANSACTION+2,
        ADD = IBinder::FIRST_CALL_TRANSACTION+3,
    };

    class BpCloudManager: public BpInterface<ICloudManager> {
    public:
        BpCloudManager(const sp<IBinder>& impl);
        virtual void test();
        virtual void print(const char* str);
        virtual int add(int a, int b);
    };
}
3) 实现实现ICloudManager接口的方法(ICloudManager.cpp)
namespace android
{
    IMPLEMENT_META_INTERFACE(CloudManager, "com.cloud.test.ICloudManager");
}
4) 实现服务端(TestServer.cpp)
namespace android
{
     //binder service 实体类
    class BnCloudManager : public BnInterface<ICloudManager>
    {
    public:
        virtual status_t
        onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
        virtual void   test();
        virtual void   print(const char* str);
        virtual int   add(int a, int b);
    };

    status_t
    BnCloudManager::onTransact(uint_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
        switch (code)
            {
        case TEST:
            {
                CHECK_INTERFACE(ICloudManager, data, reply);
                test();
                reply->writeInt32(0);
                return NO_ERROR;
            }
            break;
        case PRINT:
            {
                CHECK_INTERFACE(ICloudManager, data, reply);
                String16 str = data.readString16();
                String8 str8 = String8(str);
                print(str8.string());
                reply->writeInt32(0);
                return NO_ERROR;
            }
            break;
        case ADD:
            {
                CHECK_INTERFACE(ITest, data, reply);
                int a;
                int b;
                data.readInt32(&a);
                data.readInt32(&b);
                int c = add(a,b);
                reply->writeInt32(0);
                reply->writeInt32(c);
                return NO_ERROR;
            }
            break;
        default:
            break;
            }
        return NO_ERROR;
    }

    void
    BnCloudManager::test() {
        printf("Now server receive requset from client: [call test]\n");
    }

    void
    BnCloudManager::print(const char* str) {
        printf("Now server receive requset from client: [call print %s]\n", str);
    }

    int
    BnCloudManager::add(int a, int b) {
        printf("Now server receive requset from client: [call add %d %d]\n", a, b);
        return a + b;
    }

}
int
main() {
    sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
//注册binder service
    sm->addService(String16("cloudservice"), new BnCloudManager());
    printf("Native binder server starts to work\n");
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
    return 0;
}
5) 实现客户端(TestClient.cpp)
namespace android
{
    BpCloudManager::BpCloudManager(const sp<IBinder>& impl) :
            BpInterface<ICloudManager>(impl) {
    }
    void
    BpCloudManager::test() {
        printf("Client call server test method\n");
        Parcel data, reply;
        data.writeInterfaceToken(ICloudManager::getInterfaceDescriptor());
        remote()->transact(TEST, data, &reply);
        int code = reply.readExceptionCode();
        printf("Server exepction code: %d\n", code);
    }

    void
    BpCloudManager::print(const char* str) {
        printf("Client call server print method\n");
        Parcel data, reply;
        data.writeInterfaceToken(ICloudManager::getInterfaceDescriptor());
        data.writeString16(String16(str));
        remote()->transact(PRINT, data, &reply);
        int code = reply.readExceptionCode();
        printf("Server exepction code: %d\n", code);
    }

    int
    BpCloudManager::add(int a, int b) {
        printf("Client call server add method\n");
        Parcel data, reply;
        data.writeInterfaceToken(ICloudManager::getInterfaceDescriptor());
        data.writeInt32(a);
        data.writeInt32(b);
        remote()->transact(ADD, data, &reply);
        int code = reply.readExceptionCode();
        int result;
        reply.readInt32(&result);
        printf("Server exepction code: %d\n", code);
        return result;
    }

}

int
main() {
sp<IServiceManager> sm = defaultServiceManager();
//查询服务
sp<IBinder> binder = sm->getService(String16("cloudservice"));
//转换接口
sp<ICloudManager> cs = interface_cast<ICloudManager>(binder);
//测试接口方法
    cs->test();
    cs->print("Hello world");
    int result=cs->add(2,3);
    printf("client receive add result from server : %d\n",result);
    return 0;
}

框架层客户端

1) Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
#生成fclient.jar
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE := fclient 
LOCAL_MODULE_TAGS := optional
include $(BUILD_JAVA_LIBRARY)
#生成fclient
include $(CLEAR_VARS)
LOCAL_MODULE := fclient
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT)/bin
LOCAL_MODULE_CLASS := UTILITY_EXECUTABLES
LOCAL_SRC_FILES := fclient
include $(BUILD_PREBUILT)
2) 定义接口类(ICloudManager.java)
    public interface ICloudManager extends IInterface {
        //接口描述字符串
        static final java.lang.String DESCRIPTOR = "com.cloud.test.ICloudManager";

        void test() throws RemoteException;

        void print(String str) throws RemoteException;

        int add(int a, int b) throws RemoteException;

        static final int TRANSACTION_test = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
        static final int TRANSACTION_print = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
        static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
    }
3) 定义接口代理类(CloudManagerProxy.java)
public class CloudManagerProxy implements ICloudManager {
    private android.os.IBinder mRemote;

    public CloudManagerProxy(android.os.IBinder remote) {
        mRemote = remote;
    }

    public java.lang.String getInterfaceDescriptor() {
        return DESCRIPTOR;
    }

    @Override
    public void print(String str) throws RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
            _data.writeInterfaceToken(DESCRIPTOR);
            _data.writeString(str);
            mRemote.transact(TRANSACTION_print, _data, _reply, 0);
            _reply.readException();
        } finally {
            _reply.recycle();
            _data.recycle();
        }
    }

    @Override
    public int add(int a, int b) throws RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        int result = 0;
        try {
            _data.writeInterfaceToken(DESCRIPTOR);
            _data.writeInt(a);
            _data.writeInt(b);
            mRemote.transact(TRANSACTION_add, _data, _reply, 0);
            _reply.readException();
            result = _reply.readInt();
        } finally {
            _reply.recycle();
            _data.recycle();
        }
        return result;
    }

    @Override
    public IBinder asBinder() {
        return mRemote;
    }

    @Override
    public void test() throws RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain(); 
        try {
            _data.writeInterfaceToken(DESCRIPTOR); 
            mRemote.transact(TRANSACTION_test, _data, _reply, 0);
            _reply.readException(); 
        } finally {
            _reply.recycle();
            _data.recycle();
        }

    }
}
4) 客户端(FClient.java)
public class FClient { 

    /**
     * Command-line entry point.
     * 
     * @param args
     *            The command-line arguments
     * @throws RemoteException
     */
    public static void main(String[] args) throws RemoteException {
        System.out.println("==========Client starts===========");
        IBinder binder = ServiceManager.getService("cloudservice");
        ICloudManager manager = new CloudManagerProxy(binder);
        System.out.println("========== client call server  test ===========");
        manager.test();
        System.out.println("========== client call server print ===========");
        manager.print("Hello world");
        System.out.println("========== client call server add ===========");
        int result = manager.add(2, 3);
        System.out.println("manager.add(2, 3)=" + result);
    }
}
5) 客户端脚本fclient
# Script to start "am" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=$base/framework/fclient.jar
exec app_process $base/bin com.cloud.test.FClient "$@"

应用层客户端

先前我们有讲到在应用层是不能直接使用ServiceManager这个类的,因为Sdk并未包含该类,应用层只能通过bind service去使用binder service,但是我们的native service并不是使用应用层的Service子类创建的,这样看来貌似应用层不能使用native的binder service。

这里介绍一个技巧,其实我们的应用在运行时可以使用系统隐藏的类,比如ServiceManager,SystemProperties,只是编译 时Sdk并未提供这些类,我们若使用这些类就无法编译。但是我们可以创建这些类所在的包,并创建这些类,在类里定义我们要使用的那些方法,我们就可以通过 编译了。比如ServiceManager这个类,我们就可以为之创建android.os这个package,并在这个package下创建 ServiceManager类,定义我们需要的方法getService。也许读者会担心运行时使用的ServiceManger类就是我们创建的 ServiceManager类,但实际上运行时使用的ServiceManager类是framework.jar里的ServiceManager 类,这是因为classloader在查找类时优先使用系统的类。

1) Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_STATIC_JAVA_LIBRARIES := android-support-v13
LOCAL_STATIC_JAVA_LIBRARIES += android-support-v4

LOCAL_SRC_FILES := $(call all-java-files-under, src)

LOCAL_PACKAGE_NAME := NativeBinderServiceTest  
#LOCAL_PROGUARD_FLAG_FILES := proguard.flags

include $(BUILD_PACKAGE)

# Use the following include to make our test apk.
include $(call all-makefiles-under,$(LOCAL_PATH))
2) 我们创建的ServiceManager源码
public class ServiceManager {

    public static IBinder getService(String name) {
        return null;
    }

}
3) 定义接口ICloudManager
public interface ICloudManager extends IInterface {
    static final java.lang.String DESCRIPTOR = "com.cloud.test.ICloudManager";

    void test() throws RemoteException;

    void print(String str) throws RemoteException;

    int add(int a, int b) throws RemoteException;

    static final int TRANSACTION_test = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    static final int TRANSACTION_print = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
    static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
}
4) 定义代理类CloudManagerProxy

public class CloudManagerProxy implements ICloudManager {
    private android.os.IBinder mRemote;

    public CloudManagerProxy(android.os.IBinder remote) {
        mRemote = remote;
    }

    public java.lang.String getInterfaceDescriptor() {
        return DESCRIPTOR;
    }

    @Override
    public void print(String str) throws RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
            _data.writeInterfaceToken(DESCRIPTOR);
            _data.writeString(str);
            mRemote.transact(TRANSACTION_print, _data, _reply, 0);
            _reply.readException();
        } finally {
            _reply.recycle();
            _data.recycle();
        }
    }

    @Override
    public int add(int a, int b) throws RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        int result = 0;
        try {
            _data.writeInterfaceToken(DESCRIPTOR);
            _data.writeInt(a);
            _data.writeInt(b);
            mRemote.transact(TRANSACTION_add, _data, _reply, 0);
            _reply.readException();
            result = _reply.readInt();
        } finally {
            _reply.recycle();
            _data.recycle();
        }
        return result;
    }

    @Override
    public IBinder asBinder() {
        return mRemote;
    }

    @Override
    public void test() throws RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain(); 
        try {
            _data.writeInterfaceToken(DESCRIPTOR); 
            mRemote.transact(TRANSACTION_test, _data, _reply, 0);
            _reply.readException(); 
        } finally {
            _reply.recycle();
            _data.recycle();
        }

    }

}

5) 测试用的Activity(TestAc.java)
public class CloudManagerProxy implements ICloudManager {
    private android.os.IBinder mRemote;

    public CloudManagerProxy(android.os.IBinder remote) {
        mRemote = remote;
    }

    public java.lang.String getInterfaceDescriptor() {
        return DESCRIPTOR;
    }

    @Override
    public void print(String str) throws RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
            _data.writeInterfaceToken(DESCRIPTOR);
            _data.writeString(str);
            mRemote.transact(TRANSACTION_print, _data, _reply, 0);
            _reply.readException();
        } finally {
            _reply.recycle();
            _data.recycle();
        }
    }

    @Override
    public int add(int a, int b) throws RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        int result = 0;
        try {
            _data.writeInterfaceToken(DESCRIPTOR);
            _data.writeInt(a);
            _data.writeInt(b);
            mRemote.transact(TRANSACTION_add, _data, _reply, 0);
            _reply.readException();
            result = _reply.readInt();
        } finally {
            _reply.recycle();
            _data.recycle();
        }
        return result;
    }

    @Override
    public IBinder asBinder() {
        return mRemote;
    }

    @Override
    public void test() throws RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain(); 
        try {
            _data.writeInterfaceToken(DESCRIPTOR); 
            mRemote.transact(TRANSACTION_test, _data, _reply, 0);
            _reply.readException(); 
        } finally {
            _reply.recycle();
            _data.recycle();
        }

    }

}

4.测试

上传程序:

adb push native_bclient /system/bin
adb push native_bserver /system/bin
adb push fclient /system/bin
adb push fclient.jar /system/framework
adb shell chmod 755 /system/bin/native_bserver
adb shell chmod 755 /system/bin/native_bclient
adb shell chmod 755 /system/bin/fclient

使用native_client测试:
这里写图片描述
使用框架层的client测试:
这里写图片描述
使用应用层的client测试:

服务端:
这里写图片描述
客户端:
这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值