binder是android里面的通信机制,这就不说它如何如何好了,Goog已经说过了,这里不多说。binder是一个面向对象的编程方法,大量使用虚函数类。最近研究binder看到一网友写的,就借鉴一下。这个例子很好的解释里binder通信关系。原文:http://blog.csdn.net/new_abc/article/details/8097775 例子不错不过就是没运行起来,不过这都不是问题,关键是很容易理解。
我将他的源码整理类图看看,不过这个是简单的继承关系。
基本上使用binder就这个关系,从中间一分为二,左边客户端使用,右边服务端。不管是客户端还是服务端都继承子IXXXService这个类,这个类可以裂解为客户端和服务端的“爷爷”,而“爷爷”继承IInterface,所有自定义的binder都必须继承这个类,这个是android强指针实现计数的方法。先看看源码后再理解这个图。
首先看下目录结构:
TestBinderClient目录: Android.mk ITestBinderService.cpp
TestBinderServer目录: Android.mk ITestBinderService.h main_testBinder.cpp testBinder.cpp TestBinderService.cpp TestBinderService.h
TestBinderClient下面是Binder的客户端,TestBinderServer是binder的服务端
我们先来看下biner服务端代码
1、ITestBinderService.h
1 #ifndef ANDROID_ITESTBINDERSERVICE_H_
2 #define ANDROID_ITESTBINDERSERVICE_H_
3
4 #include <utils/RefBase.h>
5 #include <binder/IInterface.h>
6 #include <binder/Parcel.h>
7
8
9 namespace android {
10
11 class Parcel;
12
13 class ITestBinderService: public IInterface {
14 public:
15 DECLARE_META_INTERFACE(TestBinderService);
16
17 virtual int add(int a, int b) = 0;
18 };
19
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 };
25
26 }
27
28 #endif /* ANDROID_ITESTBINDERSERVICE_H_ */
ITestBinderService.h
这里主要是定义了两个类ITestBinderService 和 BnTestBinderService,ITestBinderService 是TestBinderService 的基类,这里主要是DECLARE_META_INTERFACE 这个宏,定义在frameworksbaseincludebinderIInterface.h文件中。
1 #define DECLARE_META_INTERFACE(INTERFACE)
2 static const android::String16 descriptor;
3 static android::sp<I##INTERFACE> asInterface(
4 const android::sp<android::IBinder>& obj);
5 virtual const android::String16& getInterfaceDescriptor() const;
6 I##INTERFACE();
7 virtual ~I##INTERFACE();
DECLARE_META_INTERFACE 宏
把TestBinderService代入进去
1 #define DECLARE_META_INTERFACE(TestBinderService)
2 static const android::String16 descriptor;
3 static android::sp<ITestBinderService> asInterface(
4 const android::sp<android::IBinder>& obj);
5 virtual const android::String16& getInterfaceDescriptor() const;
6 ITestBinderService();
7 virtual ~I##TestBinderService();
带入宏后
其中封装了实现binder所需要的一些类成员变量和成员函数,通过这些成员函数可以为一个binder实现创建proxy(代理)
2、TestBinderService.h
1 #ifndef ANDROID_TESTBINDERSERVICE_H_
2 #define ANDROID_TESTBINDERSERVICE_H_
3
4 #include <utils/KeyedVector.h>
5 #include "ITestBinderService.h"
6
7 namespace android {
8
9 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 };
17
18 }
19
20 #endif /* ANDROID_TESTBINDERSERVICE_H_ */
TestBinderService.h
这个文件比较简单,主要就是定义了一个类TestBinderService,继承于前面 的BnTestBinderService,并定义了一个方法add函数和instantiate
3、TestBinderService.cpp
1 #define LOG_TAG "TestBinderService"
2 #include <utils/Log.h>
3 #include <binder/IServiceManager.h>
4 #include <binder/IPCThreadState.h>
5
6 #include "TestBinderService.h"
7 static int debug_flag = 1;
8 namespace android {
9
10 void TestBinderService::instantiate() {
11 LOGI("Enter TestBinderService::instantiate");
12 status_t st = defaultServiceManager()->addService(
13 String16("my.test.binder"), new TestBinderService());
14 LOGD("ServiceManager addService ret=%d", st);
15 LOGD("instantiate> end");
16 }
17
18 TestBinderService::TestBinderService() {
19 LOGD(" TestBinderServicet");
20 }
21
22 TestBinderService::~TestBinderService() {
23 LOGD("TestBinderService destroyed,never destroy normally");
24 }
25
26 int TestBinderService::add(int a,int b) {
27
28 LOGI("TestBinderService::add a = %d, b = %d.", a , b);
29 return a+b;
30 }
31
32 }
TestBinderService.cpp
在instantiate函数中,将TestBinderService注册到系统的binder service列表中,这样以后就可以使用这个service提供的方法,该service提供了一个add 方法,返回两个数的和。
再来看下clinet端 的代码
1、ITestBinderService.cpp
1 #define LOG_TAG "ITeeveePlayerService"
2
3 #include <utils/Log.h>
4
5 #include "../TestBinderServer/ITestBinderService.h"
6
7 namespace android {
8
9 enum {
10 TEST_ADD = IBinder::FIRST_CALL_TRANSACTION,
11 };
12
13 class BpTestBinderService: public BpInterface<ITestBinderService> {
14 public:
15 BpTestBinderService(const sp<IBinder>& impl) :
16 BpInterface<ITestBinderService> (impl) {
17 }
18
19 int add(int a, int b) {
20
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 };
32
33 IMPLEMENT_META_INTERFACE(TestBinderService, "android.test.ITestBinderService");
34
35 // ----------------------------------------------------------------------
36
37 status_t BnTestBinderService::onTransact(uint32_t code, const Parcel& data,
38 Parcel* reply, uint32_t flags) {
39 switch (code) {
40 case TEST_ADD: {
41
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 }
56
57 }
ITestBinderService.cpp
定义了一个类BpTestBinderService,提供add方法,该方法通过调用远端的binder service提供的服务返回两个数的和重载了BnTestBinderService的onTransact方法,使其在TEST_ADD时调用add方法
这个文件里面也使用了一个宏IMPLEMENT_META_INTERFACE,也是定义在frameworksbaseincludebinderIInterface.h文件中
1 #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)
2 const android::String16 I##INTERFACE::descriptor(NAME);
3 const android::String16&
4 I##INTERFACE::getInterfaceDescriptor() const {
5 return I##INTERFACE::descriptor;
6 }
7 android::sp<I##INTERFACE> I##INTERFACE::asInterface(
8 const android::sp<android::IBinder>& obj)
9 {
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() { }
IMPLEMENT_META_INTERFACE宏
代入展开后:
1 #define IMPLEMENT_META_INTERFACE(TestBinderService, "android.test.ITestBinderService")
2 const android::String16 ITestBinderService::descriptor("android.test.ITestBinderService");
3 const android::String16&
4 ITestBinderService::getInterfaceDescriptor() const {
5 return ITestBinderService::descriptor;
6 }
7 android::sp<ITestBinderService> ITestBinderService::asInterface(
8 const android::sp<android::IBinder>& obj)
9 {
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() { }
带入到宏后
这样,server和client端的binder代码主写好了,接着就需要把binder service加入到binder中
这里有两种方法:
1、在system_init.cpp中添加
TestBinderService::instantiate();
如果是在这里加的话可以去掉TestBinderService中实现的instantiate方法,同时将TestBinderService继 承自BinderService,因为在BinderService实现了这一方法,同时将其添加到binder service
2、以单独的程序启动
main_testBinder.cpp
1 #include <binder/IPCThreadState.h>
2 #include <binder/ProcessState.h>
3 #include <binder/IServiceManager.h>
4 #include <utils/Log.h>
5
6
7 #include "TestBinderService.h"
8
9 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;
22
23 }
将server添加到servermanage里面
这里调用的是TestBinderService自己的instantiate来添加的
再来看下测试testBinder.cpp
1 #define LOG_TAG "TestBinserService"
2
3 #include <utils/Log.h>
4 #include <nativehelper/jni.h>
5 #include <nativehelper/JNIHelp.h>
6 #include <android_runtime/AndroidRuntime.h>
7 #include <binder/IServiceManager.h>
8 #include "../TestBinderServer/ITestBinderService.h"
9
10
11 #include "TestBinderService.h"
12
13 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 }
testBinder.cpp
以上就是测试代码。
原文链接: https://www.cnblogs.com/winfu/p/5853586.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/240159
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!