Android Binder 简单实例
2014-05-19 10:57
274 查看
最近有接触到Android的Binder通信,把自己的测试记录下来。
百度Binder很容易知道Binder在Android中的重要性,所以,这边就结合代码说明下Binder的使用sample。
使用Binder首选需要创建一个接口类,就是平常我们所见的“Ixxx”类型,它是继承了IInterface类。
DECLARE_META_INTERFACE(..)是将类型申明为接口必须的宏,展开后:
百度Binder可以知道,要使用Binder,应该创建一个Bp端,sample的Bp端代码如下:
BpTest.hpp:
BnTest.hpp:
所以,我们需要创建一个类型在服务端,使其与客户端相匹配。sample如下:
IMPLEMENT_META_INTERFACE(),看到了吗?这里和DECLARE_META_INTERFACE()是相匹配的,这边会把接口的descriptor成员变量赋值,使其能在server端找到唯一标识。
这些工作做完以后,就可以使用ITest这个类型去使用Binder通信了。
下面是两个main函数,作为测试程序:
如果服务端和客户端的创建都在同一个进程中,interface_cast<Ixx>会直接获得xx的Bn实例,就是相当于直接声明了一个xx类型。
例如,如果上面的两个main的内容合在一个main中,那么,输出的结果就会使是“BnTest DisplayText”,而不会是“<hellowold>”。
展开interface_cast,可以看到,interface_cast其实是一个模板函数:
至于Binder是如何区分是本地调用Bn还是夸进程调用,这就涉及到驱动那块了,其实跟应用的话,关系不大,有兴趣可以继续深入了解Binder的驱动部分。
百度Binder很容易知道Binder在Android中的重要性,所以,这边就结合代码说明下Binder的使用sample。
使用Binder首选需要创建一个接口类,就是平常我们所见的“Ixxx”类型,它是继承了IInterface类。
ITest.hpp class ITest: public IInterface{ public: /** @brief Declaration of TvplayerTsDemux class */ DECLARE_META_INTERFACE(Test); virtual void DisplayText()=0; };
DECLARE_META_INTERFACE(..)是将类型申明为接口必须的宏,展开后:
#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(); \DECLARE_META_INTERFACE(..)是对一些成员函数和成员变量的声明。
百度Binder可以知道,要使用Binder,应该创建一个Bp端,sample的Bp端代码如下:
BpTest.hpp:
class BpTest: public BpInterface<ITest>{ public: virtual void DisplayText(); BpTest(const sp<IBinder>& impl): BpInterface<ITest>(impl) { } };与之相对应的,就要有个Bn端,sample的Bn端代码如下:
BnTest.hpp:
class BnTest: public BnInterface<ITest>{ public: virtual status_t onTransact (uint32_t code, const Parcel& data, Parcel * reply, uint32_t flags = 0); };上面所说的Bp端和Bn端,其实都是存在与客户端的,也就是说,即使我在进程中,正确获得了客户端的Bp和Bn,服务端也不找不到相对应的类型。
所以,我们需要创建一个类型在服务端,使其与客户端相匹配。sample如下:
class Test: public BnTest { void DisplayText(); };这样,我们就声明了所有需要的类型,接下来,实现这些类的的方法。
ITest.cpp status_t BnTest::onTransact (uint32_t code, const Parcel& data, Parcel * reply, uint32_t flags ){ status_t status = NO_ERROR; printf("<hellowold>\n"); reply->writeInt32(10); return status; } void BpTest::DisplayText() { Parcel data, reply; data.writeInterfaceToken (ITest::descriptor); status_t status = remote ()->transact (1, data, &reply); if(status != NO_ERROR) { printf("File : %s Function : %s Line : %d \n", __FILE__, __FUNCTION__, __LINE__); } else { status = reply.readInt32 (); printf("<hellowold>get from binde:%d\n",status); } return; } IMPLEMENT_META_INTERFACE(Test, "com.test.test");
IMPLEMENT_META_INTERFACE(),看到了吗?这里和DECLARE_META_INTERFACE()是相匹配的,这边会把接口的descriptor成员变量赋值,使其能在server端找到唯一标识。
Test.cpp: void Test::DisplayText(){ printf("BnTest DisplayText\n"); }
这些工作做完以后,就可以使用ITest这个类型去使用Binder通信了。
下面是两个main函数,作为测试程序:
main.cpp int main(int argc, char ** argv){ printf("bp end\n"); sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> testbinder; sp<ITest> bptest; while(1) { testbinder = sm->getService (ITest::descriptor); if(testbinder!=0) break; } printf("get service\n"); bptest= interface_cast<ITest>( testbinder ); printf("get bp\n"); bptest->DisplayText(); return 1; }从代码中可以看到,这其实是客户端的Bp使用。我们先需要在server中通过唯一标识找到相应的服务端的Bn处理,然后通过interface_cast来转化为接口类型。之后就能像本地进程中的类一样来使用了。
main1.cpp Test * bntest; int main(){ printf("main start\n"); sp<IServiceManager> sm = defaultServiceManager(); // sp<IBinder> binder = sm->asBinder(); /*Instantiate And Register With Service Manager*/ bntest = new Test(); sm->addService(String16(ITest::descriptor), bntest ); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); printf("add bn\n"); return 1; }main1.cpp是服务端的Bn,他主要工作是在服务端创建对应的Bn,然后将其加入到server的服务表里,需要注意,最后的打印是不会出现的,因为在之前已经进入到了进程的无限循环中。
如果服务端和客户端的创建都在同一个进程中,interface_cast<Ixx>会直接获得xx的Bn实例,就是相当于直接声明了一个xx类型。
例如,如果上面的两个main的内容合在一个main中,那么,输出的结果就会使是“BnTest DisplayText”,而不会是“<hellowold>”。
展开interface_cast,可以看到,interface_cast其实是一个模板函数:
IInterface.h template<typename INTERFACE> inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj) { return INTERFACE::asInterface(obj); }而return的INTERFACE::asInterface其实是在DECLARE_META_INTERFACE()中声明和在IMPLEMENT_META_INTERFACE()中实现的。
至于Binder是如何区分是本地调用Bn还是夸进程调用,这就涉及到驱动那块了,其实跟应用的话,关系不大,有兴趣可以继续深入了解Binder的驱动部分。
相关文章推荐
- Android简单数据存储类SharedPreferences详解及实例(通过“记住密码”功能学习SharedPreferences)
- Android文本自动提示框的简单应用实例
- Android JNI简单实例(android 调用C/C++代码)
- Android文本自动提示框的简单应用实例
- Android OpenGL 简单实例
- Android JNI简单实例(android 调用C/C++代码)
- Android上传文件到PC的简单实例
- Android多媒体学习一:Android中Image的简单实例。
- 【Android学习日记】(六) SQLite的简单实例
- android一个简单的线程实例
- Android上传文件到服务器中的简单实例
- Android Service使用方法--简单音乐播放实例
- Android多媒体学习一:Android中Image的简单实例。
- 初识Android之简单实例
- Android深入浅出系列之实例应用—简单的手指拖动图片,图片滑来滑去显示应用Gallery和BaseAdapter以及ImageView的使用
- Android简单数据存储类SharedPreferences详解及实例
- Android多媒体学习一:Android中Image的简单实例。
- android binder机制之——(我是binder实例)
- 一个简单实用的Android蓝牙程序实例
- android Binder 实例