BInder方面的资料虽然感觉看的比较多,但是真正用的时候才发现有很多地方模棱两棵的,所以,打算用一个实例再来巩固一下binder的使用方法
首先看下目录结构:
leaves@leaves-desktop:~/android/android2/android/frameworks/tv_print/services$ ls T* TestBinderClient: Android.mk ITestBinderService.cpp TestBinderServer: Android.mk ITestBinderService.h main_testBinder.cpp testBinder.cpp TestBinderService.cpp TestBinderService.h leaves@leaves-desktop:~/android/android2/android/frameworks/tv_print/services$
我们先来看下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_ */
这里主要是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();
#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
#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_ */
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; } }
该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() { }
sp<IInterface> IBinder::queryLocalInterface(const String16& descriptor) { return NULL; }由此可见,最终会调用下面语句:
这样,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; }
再来看下测试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:
C:\adb>adb shell # cd /system/bin cd /system/bin # chmod 777 main_* chmod 777 main_* # ./main_testBinder ./main_testBinder
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 fail 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/ ( 1373): TestBinderService before I/TestBinderService( 1373): Enter TestBinderService::instantiate D/TestBinderService( 1373): TestBinderServicet D/TestBinderService( 1373): ServiceManager addService ret=0 D/TestBinderService( 1373): instantiate> end I/ ( 1373): TestBinderService End I/ITeeveePlayerService( 1369): Enter BpTestBinderService add,a = 3 , b = 4 I/ITeeveePlayerService( 1373): Enter BnTestBinderService add,a = 3 , b = 4 I/TestBinderService( 1373): TestBinderService::add a = 3, b = 4. I/ITeeveePlayerService( 1373): BnTestBinderService sum = 7 I/ITeeveePlayerService( 1369): BpTestBinderService sum = 7 I/PlayServiceManager-JNI( 1369): sum = 7前面 的Waiting for service my.test.binder...是在还没有启动service的时候打印出来的
这样,需要使用TestBinserService 提供的服务时,只需要先获取其service,再使用其提供的方法
相关代码:
http://download.csdn.net/detail/new_abc/4673623