一圖摸清Android系統(tǒng)服務(wù)的獲取和注冊流程~
大綱:
- 獲取系統(tǒng)服務(wù)
- 注冊系統(tǒng)服務(wù)
- 獨立進(jìn)程的服務(wù)
- 非獨立進(jìn)程的服務(wù)
- 總結(jié)
- 參考資料
本文約1.9k字,閱讀大約8分鐘。
Android源碼基于8.0。
先預(yù)覽下整體流程~

開始分析!
獲取系統(tǒng)服務(wù)
在日常開發(fā)中,可以通過Context.getSystemService()在自己的應(yīng)用程序里獲取到系統(tǒng)服務(wù):
//ContextImpl.java
public Object getSystemService(String name) {
//SystemServiceRegistry是系統(tǒng)服務(wù)的注冊表,用來集中管理系統(tǒng)服務(wù)
return SystemServiceRegistry.getSystemService(this, name);
}
//SystemServiceRegistry.java
public static Object getSystemService(ContextImpl ctx, String name) {
//根據(jù)服務(wù)名字從HashMap中取出ServiceFetcher
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
//傳入上下文,借助ServiceFetcher來獲取系統(tǒng)服務(wù)
return fetcher != null ? fetcher.getService(ctx) : null;
}
ServiceFetcher是一個抽象接口,抽象類CachedServiceFetcher實現(xiàn)了他,
//CachedServiceFetcher.java
public final T getService(ContextImpl ctx) {
//每個上下文ctx都有一份系統(tǒng)服務(wù)緩存
final Object[] cache = ctx.mServiceCache;
synchronized (cache) {
//從緩存里獲取系統(tǒng)服務(wù)
Object service = cache[mCacheIndex];
if (service == null) {
//緩存里沒有,則創(chuàng)建
service = createService(ctx);
//存入緩存
cache[mCacheIndex] = service;
}
return (T)service;
}
}
//createService是個抽象方法
public abstract T createService(ContextImpl ctx);
在SystemServiceRegistry里有個靜態(tài)代碼塊static{}會“注冊服務(wù)”,從中實現(xiàn)抽象方法createService()的邏輯,以電源服務(wù)PowerManager為例,
//SystemServiceRegistry.java
registerService(
Context.POWER_SERVICE, PowerManager.class,
new CachedServiceFetcher<PowerManager>() {
@Override
public PowerManager createService(ContextImpl ctx){
//ServiceManager根據(jù)服務(wù)名字獲取系統(tǒng)服務(wù)的Binder對象
IBinder b = ServiceManager.getServiceOrThrow(Context.POWER_SERVICE);
//將服務(wù)端的Binder轉(zhuǎn)成客戶端所需的AIDL接口類型的對象IPowerManager
IPowerManager service = IPowerManager.Stub.asInterface(b);
//再用PowerManager類包一層,方便外部使用
return new PowerManager(ctx.getOuterContext(),
service,
ctx.mMainThread.getHandler());
}});
AIDL可以輔助生成用于binder通信的類,IPowerManager就是定義在IPowerManager.aidl里的,binder內(nèi)部細(xì)節(jié)本文不做討論。
ServiceManager的getServiceOrThrow()函數(shù)會調(diào)用getService(),
//ServiceManager.java
public static IBinder getService(String name) {
//取緩存
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
//取不到就繼續(xù),這里創(chuàng)建完并沒有存入sCache,即sCache只是預(yù)置了一些啟動階段存入的服務(wù)
//getService()獲取系統(tǒng)服務(wù)的Binder對象,用allowBlocking包了一下,允許阻塞
return Binder.allowBlocking(getIServiceManager().getService(name));
}
return null;
}
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
//binder跨進(jìn)程通信:
//BinderInternal.getContextObject()得到系統(tǒng)級別上下文的IBinder,可用來查找服務(wù)
//asInterface將IBinder轉(zhuǎn)成IServiceManager(本質(zhì)是BpServiceManager)
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
可見,我們的應(yīng)用程序進(jìn)程會通過binder跨進(jìn)程通信,拿到ServiceManager進(jìn)程的IServiceManager對象(本質(zhì)是BpServiceManager),然后就可以通過IServiceManager對象的getService來獲取系統(tǒng)服務(wù)了。
public interface IServiceManager extends IInterface{
//從IServiceManager獲取系統(tǒng)服務(wù),如果服務(wù)不存在,會阻塞最多5秒,直到服務(wù)被發(fā)布注冊
public IBinder getService(String name);
}
看下IServiceManager的具體實現(xiàn),在IServiceManager.cpp文件里,有個BpServiceManager類,
//class BpServiceManager : public BpInterface<IServiceManager>
//這里的BpInterface是binder內(nèi)部的細(xì)節(jié)了,不是很理解,后面抽時間看看
virtual sp<IBinder> getService(const String16& name) const
{
unsigned n;
//如果獲取不到,則休眠1秒再取,最多阻塞5秒
for (n = 0; n < 5; n++){
if (n > 0) {
//休眠1秒,待會再取
sleep(1);
}
sp<IBinder> svc = checkService(name);
//獲取到系統(tǒng)服務(wù),則返回
if (svc != NULL) return svc;
}
return NULL;
}
//返回系統(tǒng)服務(wù)的binder,暫不深究
virtual sp<IBinder> checkService( const String16& name) const
{
//binder使用Parcelable來序列化數(shù)據(jù)
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
//remote()得到BpBinder,transact發(fā)送請求
remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
return reply.readStrongBinder();//Binder
}
再梳理一下系統(tǒng)服務(wù)的獲取過程:
- 應(yīng)用程序進(jìn)程調(diào)用getSystemService
- 通過binder跨進(jìn)程通信,拿到ServiceManager進(jìn)程的BpServiceManager對象
- 通過BpServiceManager獲取到系統(tǒng)服務(wù)
注冊系統(tǒng)服務(wù)
系統(tǒng)服務(wù)可以分成兩大類:
一是有獨立進(jìn)程的ServiceManager、SurfaceFlinger等,他們在init進(jìn)程啟動時就會被fork創(chuàng)建;
二是非獨立進(jìn)程的AMS、PMS、WMS等,他們在init進(jìn)程fork出Zygote進(jìn)程,Zygote進(jìn)程fork出的SystemServer進(jìn)程創(chuàng)建。
獨立進(jìn)程的服務(wù)
獨立進(jìn)程的系統(tǒng)服務(wù)在init進(jìn)程解析init.rc時啟動,比如SurfaceFlinger,看下他的啟動配置文件surfaceflinger.rc,
注:frameworks/native/services下列出了一系列服務(wù),不過ServiceManager服務(wù)放在了frameworks/native/cmds/servicemanager目錄下。
//frameworks/native/services/surfaceflinger/surfaceflinger.rc
service surfaceflinger /system/bin/surfaceflinger
class core animation
user system
group graphics drmrpc readproc
onrestart restart zygote
service以服務(wù)的形式來啟動進(jìn)程,surfaceflinger是進(jìn)程名字,/system/bin/surfaceflinger是可執(zhí)行程序的路徑,該程序的入口函數(shù)main在main_surfaceflinger.cpp,
int main(int, char**) {
//ProcessState會啟動binder機(jī)制(打開binder驅(qū)動、映射內(nèi)存、分配緩沖區(qū))
sp<ProcessState> ps(ProcessState::self());
//啟動binder線程
ps->startThreadPool();
//初始化surfaceflinger
sp<SurfaceFlinger> flinger = new SurfaceFlinger();
flinger->init();
//發(fā)布注冊surfaceflinger
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
//在當(dāng)前線程運行surfaceflinger
flinger->run();
return 0;
}
看下defaultServiceManager()的實現(xiàn),在IServiceManager.cpp,
sp<IServiceManager> defaultServiceManager()
{
//有值,直接返回
if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
//查找ServiceManager,強(qiáng)轉(zhuǎn)為IServiceManager(本質(zhì)是BpServiceManager)
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
//如果IServiceManager還是null,則休眠1秒再取,直至取到才結(jié)束循環(huán)
if (gDefaultServiceManager == NULL)
sleep(1);
}
}
return gDefaultServiceManager;
}
因為SurfaceFlinger進(jìn)程和ServiceManager進(jìn)程都是init進(jìn)程啟動的,有可能SurfaceFlinger在獲取IServiceManager時,ServiceManager還沒來得及注冊,所以這里會邊取邊休眠,取到才結(jié)束循環(huán)。
得到IServiceManager后,執(zhí)行sm->addService,在IServiceManager.cpp文件里有個BpServiceManager類,
//class BpServiceManager : public BpInterface<IServiceManager>
//這里的BpInterface是binder內(nèi)部的細(xì)節(jié)了,不是很理解,后面抽時間看看
//注冊系統(tǒng)服務(wù)(的binder),暫不深究
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated)
{
//binder使用Parcelable來序列化數(shù)據(jù)
Parcel data, reply;
data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);//Binder
data.writeInt32(allowIsolated ? 1 : 0);
//remote()得到BpBinder,transact發(fā)送請求
status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
return err == NO_ERROR ? reply.readExceptionCode() : err;
}
梳理一下:
- init進(jìn)程解析init.rc配置fork出新的進(jìn)程,啟動多項獨立進(jìn)程的系統(tǒng)服務(wù),如SurfaceFlinger
- 執(zhí)行SurfaceFlinger的可執(zhí)行程序,找到ServiceManager進(jìn)程的BpServiceManager對象
- 通過BpServiceManager執(zhí)行addService注冊服務(wù)
非獨立進(jìn)程的服務(wù)
非獨立進(jìn)程的系統(tǒng)服務(wù)由SystemServer進(jìn)程啟動,從圖解Android系統(tǒng)的啟動一文可知,SystemServer借助SystemServiceManager類(SSM)來啟動系統(tǒng)服務(wù),比如AMS,
//SystemServer.java
private void startBootstrapServices() {
//AMS由SSM創(chuàng)建啟動
mActivityManagerService = mSystemServiceManager
//創(chuàng)建并啟動AMS服務(wù)
.startService(ActivityManagerService.Lifecycle.class)
//通過binder獲取AMS服務(wù)
.getService();
//注冊AMS
mActivityManagerService.setSystemProcess();
}
//ActivityManagerService.java
public void setSystemProcess() {
//注冊AMS
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
}
調(diào)用了ServiceManager.addService()進(jìn)行注冊,
//ServiceManager.java
public static void addService(String name, IBinder service, boolean allowIsolated) {
//跟前邊一樣,通過binder跨進(jìn)程通信,拿到ServiceManager進(jìn)程的BpServiceManager對象
//調(diào)用BpServiceManager的addService
getIServiceManager().addService(name, service, allowIsolated);
}
可見,無論是SystemServer進(jìn)程啟動的服務(wù),還是init進(jìn)程啟動的運行在獨立進(jìn)程里的服務(wù),最終都是走ServiceManager進(jìn)程的BpServiceManager.addService進(jìn)行集中注冊。
總結(jié)
綜上,不管是由init進(jìn)程啟動的獨立進(jìn)程的系統(tǒng)服務(wù)如SurfaceFlinger,還是由SystemServer進(jìn)程啟動的非獨立進(jìn)程的系統(tǒng)服務(wù)如AMS,都是在ServiceManager進(jìn)程中完成注冊和獲取的,在跨進(jìn)程通信上使用了Android的binder機(jī)制。
不過哈迪在工作中沒怎么用過binder,所以他的內(nèi)部細(xì)節(jié)就暫時不深入了,后面抽時間再看。
再回顧一下~

系列文章: