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

首先看下目录结构:

leaves@leaves-desktop:~/android/android2/android/frameworks/tv_print/services$ ls T*TestBinderClient:Android.mk  ITestBinderService.cppTestBinderServer:Android.mk  ITestBinderService.h  main_testBinder.cpp  testBinder.cpp  TestBinderService.cpp  TestBinderService.hleaves@leaves-desktop:~/android/android2/android/frameworks/tv_print/services$ 

TestBinderClient下面是Binder的客户端,TestBinderServer是binder的服务端

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


1、ITestBinderService.h

#ifndef ANDROID_ITESTBINDERSERVICE_H_#define ANDROID_ITESTBINDERSERVICE_H_#include <utils/RefBase.h>#include <binder/IInterface.h>#include <binder/Parcel.h>namespace android {class Parcel;class ITestBinderService: public IInterface {public:DECLARE_META_INTERFACE(TestBinderService);virtual int add(int a, int b) = 0;};class BnTestBinderService: public BnInterface<ITestBinderService> {public:virtual status_t onTransact(uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags = 0);};}#endif /* ANDROID_ITESTBINDERSERVICE_H_ */

这里主要是定义了两个类ITestBinderService 和BnTestBinderService,ITestBinderService 是TestBinderService 的基类,

这里主要是DECLARE_META_INTERFACE 这个宏,定义在frameworks\base\include\binder\IInterface.h文件中

#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();  

把TestBinderService代入进去

#define DECLARE_META_INTERFACE(TestBinderService)                               \    static const android::String16 descriptor;                          \    static android::sp<I##TestBinderService> asInterface(                       \            const android::sp<android::IBinder>& obj);                  \    virtual const android::String16& getInterfaceDescriptor() const;    \    I##TestBinderService();                                                     \    virtual ~I##TestBinderService(); 
其中封装了实现binder所需要的一些类成员变量和成员函数,通过这些成员函数可以为一个binder实现创建proxy
2、TestBinderService.h

#ifndef ANDROID_TESTBINDERSERVICE_H_#define ANDROID_TESTBINDERSERVICE_H_#include <utils/KeyedVector.h>#include "ITestBinderService.h"namespace android {class TestBinderService: public BnTestBinderService {public:static void instantiate();int add(int a,int b);private:TestBinderService();virtual ~TestBinderService();};}#endif /* ANDROID_TESTBINDERSERVICE_H_ */

这个文件比较简单,主要就是定义了一个类TestBinderService,继承于前面 的BnTestBinderService,并定义了一个方法add函数和instantiate

3、TestBinderService.cpp

#define LOG_TAG "TestBinderService"#include <utils/Log.h>#include <binder/IServiceManager.h>#include <binder/IPCThreadState.h>#include "TestBinderService.h"static int debug_flag = 1;namespace android {void TestBinderService::instantiate() {LOGI("Enter TestBinderService::instantiate");status_t st = defaultServiceManager()->addService(String16("my.test.binder"), new TestBinderService());LOGD("ServiceManager addService ret=%d", st);LOGD("instantiate> end");}TestBinderService::TestBinderService() {LOGD(" TestBinderServicet");}TestBinderService::~TestBinderService() {LOGD("TestBinderService destroyed,never destroy normally");}int TestBinderService::add(int a,int b) {LOGI("TestBinderService::add a = %d, b = %d.", a , b);return a+b;}}

在instantiate函数中,将TestBinderService注册到系统的binder service列表中,这样以后就可以使用这个service提供的方法

该service提供了一个add 方法,返回两个数的和


再来看下clinet端 的代码

1、ITestBinderService.cpp

#define LOG_TAG "ITeeveePlayerService"#include <utils/Log.h>#include "../TestBinderServer/ITestBinderService.h"namespace android {enum {TEST_ADD = IBinder::FIRST_CALL_TRANSACTION,};class BpTestBinderService: public BpInterface<ITestBinderService> {public:BpTestBinderService(const sp<IBinder>& impl) :BpInterface<ITestBinderService> (impl) {}int add(int a, int b) {Parcel data, reply;LOGI("Enter BpTestBinderService add,a = %d , b = %d", a, b);data.writeInterfaceToken(ITestBinderService::getInterfaceDescriptor());data.writeInt32(a);data.writeInt32(b);remote()->transact(TEST_ADD, data, &reply);int sum = reply.readInt32();LOGI("BpTestBinderService sum = %d", sum);return sum;}};IMPLEMENT_META_INTERFACE(TestBinderService, "android.test.ITestBinderService");// ----------------------------------------------------------------------status_t BnTestBinderService::onTransact(uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags) {switch (code) {case TEST_ADD: {CHECK_INTERFACE(ITestBinderService, data, reply);int a = data.readInt32();int b = data.readInt32();LOGI("Enter BnTestBinderService add,a = %d , b = %d", a, b);int sum = 0;sum  = add(a, b);LOGI("BnTestBinderService sum = %d", sum); reply->writeInt32(sum);return sum;}default:return BBinder::onTransact(code, data, reply, flags);}}}
定义了一个类BpTestBinderService,提供add方法,该方法通过调用远端的binder service提供的服务返回两个数的和

重载了BnTestBinderService的onTransact方法,使其在TEST_ADD时调用add方法

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

#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() { } 
代入展开后:
#define IMPLEMENT_META_INTERFACE(TestBinderService, "android.test.ITestBinderService")                       \    const android::String16 ITestBinderService::descriptor("android.test.ITestBinderService");             \    const android::String16&                                            \            ITestBinderService::getInterfaceDescriptor() const {              \        return ITestBinderService::descriptor;                                \    }                                                                   \    android::sp<ITestBinderService> ITestBinderService::asInterface(                \            const android::sp<android::IBinder>& obj)                   \    {                                                                   \        android::sp<ITestBinderService> intr;                                 \        if (obj != NULL) {                                              \            intr = static_cast<ITestBinderService*>(                          \                obj->queryLocalInterface(                               \                        ITestBinderService::descriptor).get());               \            if (intr == NULL) {                                         \                intr = new BpTestBinderService(obj);                          \            }                                                           \        }                                                               \        return intr;                                                    \    }                                                                   \    ITestBinderService::ITestBinderService() { }                                    \    ITestBinderService::~ITestBinderService() { }   

这里重点看 一下asInterface函数,IBinder::queryLocalInterface函数位于framework/base/libs/binder/Binder.cpp文件中

sp<IInterface>  IBinder::queryLocalInterface(const String16& descriptor){    return NULL;}
由此可见,最终会调用下面语句:
intr = new BpTestBinderService(obj)


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

这里有两种方法:

1、在system_init.cpp中添加

TestBinderService::instantiate();

如果是在这里加的话可以去掉TestBinderService中实现的instantiate方法,同时将TestBinderService继承自BinderService,因为在BinderService实现了这一方法,同时将其添加到binder service

2、以单独的程序启动

main_testBinder.cpp

#include <binder/IPCThreadState.h>#include <binder/ProcessState.h>#include <binder/IServiceManager.h>#include <utils/Log.h>#include "TestBinderService.h"using namespace android;int main(int argc, char** argv) {sp<ProcessState> proc(ProcessState::self());sp<IServiceManager> sm = defaultServiceManager();LOGI("TestBinderService before");TestBinderService::instantiate();LOGI("TestBinderService End");ProcessState::self()->startThreadPool();IPCThreadState::self()->joinThreadPool();return 0;}

这里调用的是TestBinderService自己的instantiate来添加的


再来看下测试case,testBinder.cpp

#define LOG_TAG "TestBinserService"#include <utils/Log.h>#include <nativehelper/jni.h>#include <nativehelper/JNIHelp.h>#include <android_runtime/AndroidRuntime.h>#include <binder/IServiceManager.h>#include "../TestBinderServer/ITestBinderService.h"#include "TestBinderService.h"using namespace android;int main(int argc, char** argv) {int sum = 0;sp<ITestBinderService> mTestBinserService;if (mTestBinserService.get() == 0) {sp<IServiceManager> sm = defaultServiceManager();sp<IBinder> binder;do {binder = sm->getService(String16("my.test.binder"));if (binder != 0)break;LOGI("getService fail");usleep(500000); // 0.5 s} while (true);mTestBinserService = interface_cast<ITestBinderService> (binder);LOGE_IF(mTestBinserService == 0, "no ITestBinserService!?");}sum = mTestBinserService->add(3, 4);LOGI("sum = %d", sum);return 0;}

这里先根据名字获取Service,再使用其提供的相应 服务

看下串口打印,

启动service:

C:\adb>adb shell# cd /system/bincd /system/bin# chmod 777 main_*chmod 777 main_*# ./main_testBinder./main_testBinder

client:

I/ServiceManager( 1369): Waiting for service my.test.binder...I/ServiceManager( 1369): Waiting for service my.test.binder...I/ServiceManager( 1369): Waiting for service my.test.binder...I/ServiceManager( 1369): Waiting for service my.test.binder...I/ServiceManager( 1369): Waiting for service my.test.binder...I/PlayServiceManager-JNI( 1369): getService failI/ServiceManager( 1369): Waiting for service my.test.binder...I/ServiceManager( 1369): Waiting for service my.test.binder...I/ServiceManager( 1369): Waiting for service my.test.binder...I/ServiceManager( 1369): Waiting for service my.test.binder...I/        ( 1373): TestBinderService beforeI/TestBinderService( 1373): Enter TestBinderService::instantiateD/TestBinderService( 1373):  TestBinderServicetD/TestBinderService( 1373): ServiceManager addService ret=0D/TestBinderService( 1373): instantiate> endI/        ( 1373): TestBinderService EndI/ITeeveePlayerService( 1369): Enter BpTestBinderService add,a = 3 , b = 4I/ITeeveePlayerService( 1373): Enter BnTestBinderService add,a = 3 , b = 4I/TestBinderService( 1373): TestBinderService::add a = 3, b = 4.I/ITeeveePlayerService( 1373): BnTestBinderService sum = 7I/ITeeveePlayerService( 1369): BpTestBinderService sum = 7I/PlayServiceManager-JNI( 1369): sum = 7
前面 的Waiting for service my.test.binder...是在还没有启动service的时候打印出来的

这样,需要使用TestBinserService 提供的服务时,只需要先获取其service,再使用其提供的方法

相关代码:

http://download.csdn.net/detail/new_abc/4673623


更多相关文章

  1. Android(安卓)ListView异步加载图片时图片顺序混乱解决办法
  2. Android(安卓)listView scroll 恢复滚动位置
  3. android j使用JNI实现ava语言调用C语言
  4. Android(安卓)json通信(解析)方法
  5. Android(安卓)rom开发:webview崩溃问题Binary XML file line #103
  6. Android(安卓)网络框架初探
  7. Android中文API(125) —— VideoView
  8. Android(安卓)GridView的使用
  9. 学习Android闹钟源代码(三)-AlarmClock类分析(part2)

随机推荐

  1. Android(安卓)UI之ImageButton(带图标的
  2. Learning Android(安卓)第1章 - 工欲善其
  3. Android进程的内存管理分析
  4. Android项目优化宝典
  5. android进程在管理器中被杀死
  6. Android(安卓)高手进阶教程(十四)之----A
  7. Android(安卓)开发中Parcel存储类型和数
  8. Android(安卓)学习
  9. android - 为安全而设计 - 1 - 开发文档
  10. android mediastore