加入收藏 | 设为首页 | 会员中心 | 我要投稿 52刷机网 (https://www.52shuaji.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 安卓频道 > 安卓资讯 > 正文

Android binder机制(native服务篇)

发布时间:2017-05-16 19:04:36 所属栏目:安卓资讯 来源:www.jianshu.com
导读:1、前言Android系统使用binder机制进行进程间通信,为了更好地封装,使用户不用关心底层细节,binder机制变得相当复杂。binder使用c/s架构,可类比socket通信,有服务端也有客户端,而binder驱动就相当于网络。Paste_Image.png本文以M...

点击查看宏定义具体内容:

#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() { }                                   

将模板替换,可知asInterface方法代码为:

android::sp<IServiceManager> IServiceManager::asInterface(                         const android::sp<android::IBinder>& obj)                    {                                                                        android::sp<IServiceManager> intr;                                      if (obj != NULL) {                                                       intr = static_cast<IServiceManager*>(                                       obj->queryLocalInterface(                                                    IServiceManager::descriptor).get());                        if (intr == NULL) {                                                      intr = new BpServiceManager(obj);                                   }                                                                }                                                                    return intr;                                                     }

如果有看过java中的aidl文件,会发现这段代码和aidl被编译器自动处理过后的文件非常相似,如果client端和server端不在同一进程,那么必定走的流程是返回 BpServiceManager 。

BpServiceManager 类在哪呢?它定义在IServiceManager.cpp文件中。

一般native服务的接口定义在 I××Service.h 文件中,Bp××Service一般定义在I××Service.cpp文件当中

经过一系列的折腾,终于回到MediaPlayerService.cpp的instantiate方法了,代替下就是

void MediaPlayerService::instantiate() { BpServiceManager->addService(String16("media.player"), new MediaPlayerService()); }

4、和Binder驱动正式通信

查看BpServiceManager的addService方法

virtual status_t addService(const String16& name, const sp<IBinder>& service,         bool allowIsolated) {     Parcel data, reply;     data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());     data.writeString16(name);     data.writeStrongBinder(service);     data.writeInt32(allowIsolated ? 1 : 0);     status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);     return err == NO_ERROR ? reply.readExceptionCode() : err; }

感觉这段代码非常眼熟,和java中的aidl差别不大,主要就是调用remote()->transact,和Binder驱动通信。问题来了,那remote()方法得到的是什么对象呢?

remote()方法返回的是mRemote对象,回溯上文所讲的asInterface方法,构造BpServiceManager对象,传入了一个BpBinder,查看BpServiceManager的构造函数,它最终引用父类BpRefBase的构造函数。

BpRefBase::BpRefBase(const sp<IBinder>& o) : mRemote(o.get()), mRefs(NULL), mState(0) {    。。。。 }

于是得知addService方法中,其实是调用BpBinder的transact方法。

Android binder机制(native服务篇)
Paste_Image.png

根据在java中使用aidl的经验,调用transact方法后,最终肯定会调用到onTransact,最终调用到Server端的方法。

BpBinder的transact之后的调用流程如上,尤其关注IPCThreadState类。根据上图,IPCThreadState与Binder驱动通信,分别调用三个方法

  • writeTransactionData,向Binder驱动写数据
  • waitForResponse, 等待Binder驱动返回指令
  • executeCommand,执行Binder驱动的指令

目前和Binder驱动相关的代码已经有两个类了,一个是ProcessState,另一个是IPCThreadState,他们的关系如何,待会再说。

已经调用了onTransact方法,按理说,应该要调用Server端的方法了,可ServiceManager的server端代码在哪里呢?

(编辑:52刷机网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读