Binder使用示例

         BInder方面的资料虽然感觉看的比较多,但是真正用的时候才发现有很多地方模棱两棵的,所以,打算用一个实例再来巩固一下binder的使用方法

首先看下目录结构:

01.leaves@leaves-desktop:~/android/android2/android/frameworks/tv_print/services$ ls T* 
02.TestBinderClient: 
03.Android.mk  ITestBinderService.cpp 
05.TestBinderServer: 
06.Android.mk  ITestBinderService.h  main_testBinder.cpp  testBinder.cpp  TestBinderService.cpp  TestBinderService.h 
其中 TestBinderClient下是Binder的客户端,TestBinderServer是binder的服务端.

我们先来看下biner服务端代码:

主要是DECLARE_META_INTERFACE 这个宏,定义在frameworks\base\include\binder\IInterface.h文件中
02.    static const android::String16 descriptor;                          \ 
03.    static android::sp<I##INTERFACE> asInterface(                       \ 
04.            const android::sp<android::IBinder>& obj);                  \ 
05.    virtual const android::String16& getInterfaceDescriptor() const;    \ 
06.    I##INTERFACE();                                                     \ 
07.    virtual ~I##INTERFACE(); 
把TestBinderService代入 , 其中封装了实现binder所需要的一些类成员变量和成员函数,通过这些成员函数可以为一个binder实现创建proxy

02.    static const android::String16 descriptor;                          \ 
03.    static android::sp<I##TestBinderService> asInterface(                       \ 
04.            const android::sp<android::IBinder>& obj);                  \ 
05.    virtual const android::String16& getInterfaceDescriptor() const;    \ 
06.    I##TestBinderService();                                                     \ 
07.    virtual ~I##TestBinderService();

1、ITestBinderService.h  里主要是定义了两个类ITestBinderService 和 BnTestBinderService,ITestBinderService 是TestBinderService 的基类.
namespace android { 
11.class Parcel; 

13.class ITestBinderService: public IInterface { 
14.public: 
15.    DECLARE_META_INTERFACE(TestBinderService); 
17.    virtual int add(int a, int b) = 0; 
18.}; 
20.class BnTestBinderService: public BnInterface<ITestBinderService> { 
21.public: 
22.    virtual status_t onTransact(uint32_t code, const Parcel& data, 
23.            Parcel* reply, uint32_t flags = 0); 
24.}; 
26.}

2、TestBinderService.h 这个文件就是定义了一个类TestBinderService,继承于前面 的BnTestBinderService,并定义了一个方法add函数和instantiate .
namespace android { 
09.class TestBinderService: public BnTestBinderService { 
10.public: 
11.    static void instantiate(); 
12.    int add(int a,int b); 
13.private: 
14.    TestBinderService(); 
15.    virtual ~TestBinderService(); 
16.}; 
18.} 

3、TestBinderService.cpp  在instantiate函数中,将TestBinderService注册到系统的binder service列表中,这样以后就可以使用这个service提供的方法
该service提供了一个add 方法,返回两个数的和.
static int debug_flag = 1; 
09.namespace android { 
11.void TestBinderService::instantiate() { 
12.    LOGI("Enter TestBinderService::instantiate"); 
13.    status_t st = defaultServiceManager()->addService
14.            String16("my.test.binder"), new TestBinderService()); 
15.    LOGD("ServiceManager addService ret=%d", st); 
16.    LOGD("instantiate> end"); 
17.} 
19.TestBinderService::TestBinderService() { 
20.    LOGD(" TestBinderServicet"); 
21.} 
23.TestBinderService::~TestBinderService() { 
24.    LOGD("TestBinderService destroyed,never destroy normally"); 
25.} 
27.int TestBinderService::add(int a,int b) { 
28. 
29.    LOGI("TestBinderService::add a = %d, b = %d.", a , b);   
30.    return a+b; 
31.} 
33.} 

再来看下clinet端 的代码:

1、ITestBinderService.cpp

主要是定义了一个类BpTestBinderService,提供add方法,该方法通过调用远端的binder service提供的服务返回两个数的和,
并重载了BnTestBinderService的onTransact方法,使其在TEST_ADD时调用add方法.

namespace android { 
09.enum { 
10.    TEST_ADD = IBinder::FIRST_CALL_TRANSACTION, 
11.}; 
13.class BpTestBinderService: public BpInterface<ITestBinderService> { 
14.public: 
15.    BpTestBinderService(const sp<IBinder>& impl) : 
16.        BpInterface<ITestBinderService> (impl) { 
17.    } 
19.    int add(int a, int b) { 
21.        Parcel data, reply; 
22.        LOGI("Enter BpTestBinderService add,a = %d , b = %d", a, b); 
23.        data.writeInterfaceToken(ITestBinderService::getInterfaceDescriptor()); 
24.        data.writeInt32(a); 
25.        data.writeInt32(b); 
26.        remote()->transact(TEST_ADD, data, &reply); 
27.        int sum = reply.readInt32(); 
28.        LOGI("BpTestBinderService sum = %d", sum); 
29.        return sum; 
30.    } 
31.}; 
33.IMPLEMENT_META_INTERFACE(TestBinderService, "android.test.ITestBinderService"); 
37.status_t BnTestBinderService::onTransact(uint32_t code, const Parcel& data, 
38.        Parcel* reply, uint32_t flags) { 
39.    switch (code) { 
40.    case TEST_ADD: { 
42.        CHECK_INTERFACE(ITestBinderService, data, reply); 
43.        int a = data.readInt32(); 
44.        int b = data.readInt32(); 
45.        LOGI("Enter BnTestBinderService add,a = %d , b = %d", a, b); 
46.        int sum = 0; 
47.        sum  = add(a, b); 
48.        LOGI("BnTestBinderService sum = %d", sum); 
49.         reply->writeInt32(sum); 
50.        return sum; 
51.    } 
52.    default: 
53.        return BBinder::onTransact(code, data, reply, flags); 
54.    } 
55.} 
57.} 

这个文件里面也使用了一个宏IMPLEMENT_META_INTERFACE,也是定义在frameworks\base\include\binder\IInterface.h文件中:

02.    const android::String16 I##INTERFACE::descriptor(NAME);             \ 
03.    const android::String16&                                            \ 
04.            I##INTERFACE::getInterfaceDescriptor() const {              \ 
05.        return I##INTERFACE::descriptor;                                \ 
06.    }                                                                   \ 
07.    android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \ 
08.            const android::sp<android::IBinder>& obj)                   \ 
09.    {                                                                   \ 
10.        android::sp<I##INTERFACE> intr;                                 \ 
11.        if (obj != NULL) {                                              \ 
12.            intr = static_cast<I##INTERFACE*>(                          \ 
13.                obj->queryLocalInterface(                               \ 
14.                        I##INTERFACE::descriptor).get());               \ 
15.            if (intr == NULL) {                                         \ 
16.                intr = new Bp##INTERFACE(obj);                          \ 
17.            }                                                           \ 
18.        }                                                               \ 
19.        return intr;                                                    \ 
20.    }                                                                   \ 
21.    I##INTERFACE::I##INTERFACE() { }                                    \ 
22.    I##INTERFACE::~I##INTERFACE() { } 

代入展开后:
02.    const android::String16 ITestBinderService::descriptor("android.test.ITestBinderService");             \ 
03.    const android::String16&                                            \ 
04.            ITestBinderService::getInterfaceDescriptor() const {              \ 
05.        return ITestBinderService::descriptor;                                \ 
06.    }                                                                   \ 
07.    android::sp<ITestBinderService> ITestBinderService::asInterface(                \ 
08.            const android::sp<android::IBinder>& obj)                   \ 
09.    {                                                                   \ 
10.        android::sp<ITestBinderService> intr;                                 \ 
11.        if (obj != NULL) {                                              \ 
12.            intr = static_cast<ITestBinderService*>(                          \ 
13.                obj->queryLocalInterface(                               \ 
14.                        ITestBinderService::descriptor).get());               \ 
15.            if (intr == NULL) {                                         \ 
16.                intr = new BpTestBinderService(obj);                          \ 
17.            }                                                           \ 
18.        }                                                               \ 
19.        return intr;                                                    \ 
20.    }                                                                   \ 
21.    ITestBinderService::ITestBinderService() { }                                    \ 
22.    ITestBinderService::~ITestBinderService() { }

这里重点看 一下asInterface函数,IBinder::queryLocalInterface函数位于framework/base/libs/binder/Binder.cpp文件中
01.sp<IInterface>  IBinder::queryLocalInterface(const String16& descriptor) 
02.{ 
03.    return NULL; 
04.} 
此可见,最终会调用下面语句: intr = new BpTestBinderService(obj).

这样,server和client端的binder代码主写好了,接着就需要把binder service加入到binder中:

1、在system_init.cpp中添加

TestBinderService::instantiate();
2、以单独的程序启动
main_testBinder.cpp
using namespace android; 
10. 
11.int main(int argc, char** argv) 
12. { 
13.     
14.    sp<ProcessState> proc(ProcessState::self()); 
15.    sp<IServiceManager> sm = defaultServiceManager(); 
16.    LOGI("TestBinderService before"); 
17.    TestBinderService::instantiate(); 
18.    LOGI("TestBinderService End"); 
19.    ProcessState::self()->startThreadPool(); 
20.    IPCThreadState::self()->joinThreadPool(); 
21.    return 0; 
23.} 
上面调用的是TestBinderService自己的instantiate来添加的.

再来看下测试case,testBinder.cpp,这里先根据名字获取Service,再使用其提供的相应 服务.

using namespace android; 
14. 
15.int main(int argc, char** argv) 
16. { 
17.    int sum = 0; 
18.    sp<ITestBinderService> mTestBinserService; 
19.    if (mTestBinserService.get() == 0) { 
20.        sp<IServiceManager> sm = defaultServiceManager(); 
21.        sp<IBinder> binder; 
22.        do { 
23.            binder = sm->getService(String16("my.test.binder")); 
24.            if (binder != 0) 
25.                break; 
26.                LOGI("getService fail"); 
27.            usleep(500000); // 0.5 s  
28.        } while (true); 
29.        mTestBinserService = interface_cast<ITestBinderService> (binder); 
30.        LOGE_IF(mTestBinserService == 0, "no ITestBinserService!?"); 
31.    } 
32.    sum = mTestBinserService->add(3, 4); 
33.    LOGI("sum = %d", sum); 
34.    return 0; 
35. 
36.}
看下串口打印,启动service:

01.C:\adb>adb shell 
02.# cd /system/bin  
03.cd /system/bin 
04.# chmod 777 main_*  
05.chmod 777 main_* 
06.# ./main_testBinder  
07../main_testBinder 
client:
前面 的Waiting for service my.test.binder...是在还没有启动service的时候打印出来的 .
这样,需要使用TestBinserService 提供的服务时,只需要先获取其service,再使用其提供的方法.
01.I/ServiceManager( 1369): Waiting for service my.test.binder... 
02.I/ServiceManager( 1369): Waiting for service my.test.binder... 
03.I/ServiceManager( 1369): Waiting for service my.test.binder... 
11.I/        ( 1373): TestBinderService before 
12.I/TestBinderService( 1373): Enter TestBinderService::instantiate 
13.D/TestBinderService( 1373):  TestBinderServicet 
14.D/TestBinderService( 1373): ServiceManager addService ret=0 
15.D/TestBinderService( 1373): instantiate> end 
16.I/        ( 1373): TestBinderService End 
17.I/ITeeveePlayerService( 1369): Enter BpTestBinderService add,a = 3 , b = 4 
18.I/ITeeveePlayerService( 1373): Enter BnTestBinderService add,a = 3 , b = 4 
19.I/TestBinderService( 1373): TestBinderService::add a = 3, b = 4. 
20.I/ITeeveePlayerService( 1373): BnTestBinderService sum = 7 
21.I/ITeeveePlayerService( 1369): BpTestBinderService sum = 7 
22.I/PlayServiceManager-JNI( 1369): sum = 7 

 转自: http://blog.csdn.net/new_abc/article/details/8097775

 

 

 

 

 

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