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