最近有接触到Android的Binder通信,把自己的测试记录下来。

百度Binder很容易知道Binder在Android中的重要性,所以,这边就结合代码说明下Binder的使用sample。 使用Binder首选需要创建一个接口类,就是平常我们所见的“Ixxx”类型,它是继承了IInterface类。

ITest.hppclass 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 asInterface(                       \            const android::sp& 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{public:virtual void DisplayText(); BpTest(const sp& impl): BpInterface(impl) {}};
与之相对应的,就要有个Bn端,sample的Bn端代码如下:

BnTest.hpp:

class BnTest: public BnInterface{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.cppstatus_t BnTest::onTransact (uint32_t code, const Parcel& data, Parcel * reply, uint32_t flags ){status_t status = NO_ERROR;printf("\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("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.cppint main(int argc, char ** argv){printf("bp end\n"); sp sm = defaultServiceManager();sp testbinder;sp bptest;while(1){testbinder = sm->getService (ITest::descriptor);if(testbinder!=0)break;}printf("get service\n");bptest= interface_cast( 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 sm = defaultServiceManager();// sp 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会直接获得xx的Bn实例,就是相当于直接声明了一个xx类型。

例如,如果上面的两个main的内容合在一个main中,那么,输出的结果就会使是“BnTest DisplayText”,而不会是“”。

展开interface_cast,可以看到,interface_cast其实是一个模板函数:

IInterface.htemplateinline sp interface_cast(const sp& obj){    return INTERFACE::asInterface(obj);}
而return的INTERFACE::asInterface其实是在DECLARE_META_INTERFACE()中声明和在IMPLEMENT_META_INTERFACE()中实现的。

至于Binder是如何区分是本地调用Bn还是夸进程调用,这就涉及到驱动那块了,其实跟应用的话,关系不大,有兴趣可以继续深入了解Binder的驱动部分。







更多相关文章

  1. Android支持的资源
  2. 转:RTC搭建android下三层应用程序访问服务器MsSql-客户端
  3. Android(安卓)IBinder的linkToDeath介绍及情景模拟
  4. Android中EditText 的setInputType以及setRawInputType区别
  5. 用CSS3生成的一个漂亮的android客户端页面
  6. webrtc——web与android,android间通信
  7. android序列化
  8. 设置activity为Dialog类型的设置
  9. 重新解压打包android 根文件系统 ramdisk.img

随机推荐

  1. Android学习路线
  2. Android(安卓)核心分析 之八------Androi
  3. 如何解决:Android中 Error generating fin
  4. 分享17个老罗Android开发视频教程(免费下
  5. Android(安卓)进程间通信:AIDL
  6. Android(安卓)内存溢出解决方案(OOM) 整理
  7. android:shape的使用
  8. Android(安卓)NDK STL
  9. android 回车键事件编程
  10. Android(安卓)消息提示框:五种Toast详解