本文首发于微信公众号「后厂技术官」
关联系列
Android AOSP基础系列
Android系统启动系列
应用进程启动系列
Android深入四大组件系列
Android深入理解Context系列
Android深入理解JNI系列
Android解析WindowManager
Android解析WMS系列
Android解析AMS系列
Android包管理机制系列
Android输入系统系列
前言
在本系列的此前文章中,以MediaPlayerService为例,讲解了系统服务是如何注册的(addService),既然有注册那肯定也要有获取,本篇文章仍旧以MediaPlayerService为例,来讲解系统服务的获取过程(getService)。文章会分为两个部分进行讲解,分别是客户端MediaPlayerService请求获取服务和服务端ServiceManager处理请求,先来学习第一部分。
此前的系列文章见:https://liuwangshu.cn/tags/Binder%E5%8E%9F%E7%90%86/
1.客户端MediaPlayerService请求获取服务
要想获取MediaPlayerService,需要先调用getMediaPlayerService函数,如下所示。
frameworks/av/media/libmedia/IMediaDeathNotifier.cpp
IMediaDeathNotifier::getMediaPlayerService()
{
ALOGV("getMediaPlayerService");
Mutex::Autolock _l(sServiceLock);
if (sMediaPlayerService == 0) {
sp<IServiceManager> sm = defaultServiceManager();//1
sp<IBinder> binder;
do {
binder = sm->getService(String16("media.player"));//2
if (binder != 0) {
//3
break;
}
ALOGW("Media player service not published, waiting...");
usleep(500000); //4
} while (true);
if (sDeathNotifier == NULL) {
sDeathNotifier = new DeathNotifier();
}
binder->linkToDeath(sDeathNotifier);
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);//5
}
ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");
return sMediaPlayerService;
}
注释1处的defaultServiceManager返回的是BpServiceManager,注释2处获取名为”media.player”的系统服务(MediaPlayerService),返回的值为BpBinder。由于这个时候MediaPlayerService可能还没有向ServiceManager注册,那么就不能满足注释3的条件,在注释4处休眠0.5s后继续调用getService函数,直到获取服务对应的为止。
注释5处的interface_cast函数用于将BpBinder转换成BpMediaPlayerService,其原理就是通过BpBinder的handle来找到对应的服务,即BpMediaPlayerService。
注释2处的获取服务是本文的重点,BpServiceManager的getService函数如下所示。
frameworks/native/libs/binder/IServiceManager.cpp::BpServiceManager
virtual sp<IBinder> getService(const String16& name) const
{
...
int n = 0;
while (uptimeMillis() < timeout) {
n++;
if (isVendorService) {
ALOGI("Waiting for vendor service %s...", String8(name).string());
CallStack stack(LOG_TAG);
} else if (n%10 == 0) {
ALOGI("Waiting for service %s...", String8(name).string());
}
usleep(1000*sleepTime);
sp<IBinder> svc = checkService(name);//1
if (svc != NULL) return svc;
}
ALOGW("Service %s didn't start. Returning NULL", String8(name).string());
return NULL;
}
getService函数中主要做的事就是循环的查询服务是否存在,如果不存在就继续查询,查询服务用到了注释1处的checkService函数,代码如下所示。
frameworks/native/libs/binder/IServiceManager.cpp::BpServiceManager
virtual sp<IBinder> checkService( const String16& name) const
{
Parcel data, reply;//1
data