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

Android binder机制(native服务篇)

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

再次回到onTransact方法,现在server端代码找到了,client端调用了addService,那么server端响应了什么操作呢?

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

到目前为止,针对ServiceManager,从client端发起请求,到服务端响应请求的整个流程已经讲完了。

5、MediaPlayerService

根据ServiceManager的分析经验,一个本地服务至少涉及到以下几个类

  • I××Service.h,定义接口,引用宏定义等,从后文可知,它还会定义BN××Service类
  • I××Service.cpp,定义Bp××Service类,声明实现宏定义,从后文可知,它还会重写BN××Service类的onTransact方法
  • Service_manager.c,类似的看似不相关文件,打开binder驱动,初始化,循环读取binder驱动消息等
  • ××Service.cpp,ServiceManager中server端的具体逻辑实现在Service_manager中,但一般来说,会有这样的一个类,实现具体逻辑

MediaPlayerService服务的初始化在Main_mediaserver.cpp中,对应着ServiceManager系统的Service_manager.c,负责初始化,打开binder驱动,建议消息循环等等

int main(int argc __unused, char** argv) { sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm = defaultServiceManager(); MediaPlayerService::instantiate(); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); }

然道先前的推测不对?main方法中并没有直接打开binder,也没有建立消息循环。联想到前文中的内容,与Binder驱动打交道的主要有两个类,一是ProcessState,另一个就是IPCThreadState。

在ProcessState的构造方法中,已经打开了binder驱动。

从代码上看 ProcessState::self()->startThreadPool(),好像是启动线程。

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

查看IPCThreadState的joinThreadPool方法

void IPCThreadState::joinThreadPool(bool isMain) {     mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);      set_sched_policy(mMyThreadId, SP_FOREGROUND);     status_t result;     do {         processPendingDerefs();         // 从binder驱动中取出指令并执行         result = getAndExecuteCommand();     } while (result != -ECONNREFUSED && result != -EBADF);      mOut.writeInt32(BC_EXIT_LOOPER);     talkWithDriver(false); }

此方法正好是建立消息死循环,与binder驱动沟通,取指令,执行指令等等。

但为什么此方法被调用两次呢?ProcessState的startThreadPool方法调用一次,而main方法最后又调用了一次,在工程线程中调用了,在主线程也调用了。是否可去掉其中之一,笔者不得而知。

IPCThreadState::self(),此方法又做了哪些工作呢?

IPCThreadState* IPCThreadState::self() {     if (gHaveTLS) { restart:         const pthread_key_t k = gTLS;         IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);         if (st) return st;         return new IPCThreadState;     }     pthread_mutex_lock(&gTLSMutex);     if (!gHaveTLS) {         int key_create_value = pthread_key_create(&gTLS, threadDestructor);         if (key_create_value != 0) {             pthread_mutex_unlock(&gTLSMutex);             return NULL;         }         gHaveTLS = true;     }     pthread_mutex_unlock(&gTLSMutex);     goto restart; }

TLS,线程局部存储,变量与线程相关,每个线程私有,不必考虑加锁问题,类似于java中的ThreadLocal类

由此可见,IPCThreadState,它是每个线程所独有的对象。ProcessState是进程唯一的对象,这是两个非常有意思的单例。

这两个类都有与Binder驱动通信的逻辑,实质上是,IPCThreadState的构造方法中传入了ProcessState对象,IPCThreadState利用ProcessState与binder驱动通信

6、MediaPlayerService相关文件

IMediaPlayerService.h中定义了server端应该实现的接口,也定义了BnMediaPlayerService类

和前文中的IServiceManager.h一样

IMediaPlayerService.cpp中定义了BpMediaPlayerService类,也重写了BnMediaPlayerService的onTransact方法

IMediaPlayerService.h中定义的方法,在此文件中具体实现。

7、总结

MediaPlayerService的client端与server端通信,和ServiceManager模块中类似,就不再复述。

此时再结合前言中的图片,如果每个类都做到心中有数了,那native服务的binder机制就基本了解了。

(编辑:无忧刷机网 - 51刷机网)

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

热点阅读