|
再次回到onTransact方法,现在server端代码找到了,client端调用了addService,那么server端响应了什么操作呢? 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(),好像是启动线程。 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机制就基本了解了。 (编辑:52刷机网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|