一圖摸清Android系統(tǒng)服務的獲取和注冊流程~
大綱:
- 獲取系統(tǒng)服務
- 注冊系統(tǒng)服務
- 獨立進程的服務
- 非獨立進程的服務
- 總結
- 參考資料
本文約1.9k字,閱讀大約8分鐘俘种。
Android源碼基于8.0艺沼。
先預覽下整體流程~
開始分析奶栖!
獲取系統(tǒng)服務
在日常開發(fā)中盐捷,可以通過Context.getSystemService()在自己的應用程序里獲取到系統(tǒng)服務:
//ContextImpl.java
public Object getSystemService(String name) {
//SystemServiceRegistry是系統(tǒng)服務的注冊表,用來集中管理系統(tǒng)服務
return SystemServiceRegistry.getSystemService(this, name);
}
//SystemServiceRegistry.java
public static Object getSystemService(ContextImpl ctx, String name) {
//根據(jù)服務名字從HashMap中取出ServiceFetcher
ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
//傳入上下文辜腺,借助ServiceFetcher來獲取系統(tǒng)服務
return fetcher != null ? fetcher.getService(ctx) : null;
}
ServiceFetcher是一個抽象接口休建,抽象類CachedServiceFetcher實現(xiàn)了他乍恐,
//CachedServiceFetcher.java
public final T getService(ContextImpl ctx) {
//每個上下文ctx都有一份系統(tǒng)服務緩存
final Object[] cache = ctx.mServiceCache;
synchronized (cache) {
//從緩存里獲取系統(tǒng)服務
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{}會“注冊服務”测砂,從中實現(xiàn)抽象方法createService()的邏輯茵烈,以電源服務PowerManager為例,
//SystemServiceRegistry.java
registerService(
Context.POWER_SERVICE, PowerManager.class,
new CachedServiceFetcher<PowerManager>() {
@Override
public PowerManager createService(ContextImpl ctx){
//ServiceManager根據(jù)服務名字獲取系統(tǒng)服務的Binder對象
IBinder b = ServiceManager.getServiceOrThrow(Context.POWER_SERVICE);
//將服務端的Binder轉成客戶端所需的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)部細節(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只是預置了一些啟動階段存入的服務
//getService()獲取系統(tǒng)服務的Binder對象粘招,用allowBlocking包了一下,允許阻塞
return Binder.allowBlocking(getIServiceManager().getService(name));
}
return null;
}
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
//binder跨進程通信:
//BinderInternal.getContextObject()得到系統(tǒng)級別上下文的IBinder偎球,可用來查找服務
//asInterface將IBinder轉成IServiceManager(本質(zhì)是BpServiceManager)
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
可見洒扎,我們的應用程序進程會通過binder跨進程通信,拿到ServiceManager進程的IServiceManager對象(本質(zhì)是BpServiceManager)衰絮,然后就可以通過IServiceManager對象的getService來獲取系統(tǒng)服務了袍冷。
public interface IServiceManager extends IInterface{
//從IServiceManager獲取系統(tǒng)服務,如果服務不存在岂傲,會阻塞最多5秒难裆,直到服務被發(fā)布注冊
public IBinder getService(String name);
}
看下IServiceManager的具體實現(xiàn),在IServiceManager.cpp文件里镊掖,有個BpServiceManager類,
//class BpServiceManager : public BpInterface<IServiceManager>
//這里的BpInterface是binder內(nèi)部的細節(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)服務,則返回
if (svc != NULL) return svc;
}
return NULL;
}
//返回系統(tǒng)服務的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)服務的獲取過程:
- 應用程序進程調(diào)用getSystemService
- 通過binder跨進程通信,拿到ServiceManager進程的BpServiceManager對象
- 通過BpServiceManager獲取到系統(tǒng)服務
注冊系統(tǒng)服務
系統(tǒng)服務可以分成兩大類:
一是有獨立進程的ServiceManager逛球、SurfaceFlinger等千元,他們在init進程啟動時就會被fork創(chuàng)建;
二是非獨立進程的AMS颤绕、PMS幸海、WMS等祟身,他們在init進程fork出Zygote進程,Zygote進程fork出的SystemServer進程創(chuàng)建物独。
獨立進程的服務
獨立進程的系統(tǒng)服務在init進程解析init.rc時啟動袜硫,比如SurfaceFlinger,看下他的啟動配置文件surfaceflinger.rc挡篓,
注:frameworks/native/services下列出了一系列服務婉陷,不過ServiceManager服務放在了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
以服務的形式來啟動進程官研,surfaceflinger
是進程名字秽澳,/system/bin/surfaceflinger
是可執(zhí)行程序的路徑,該程序的入口函數(shù)main在main_surfaceflinger.cpp阀参,
int main(int, char**) {
//ProcessState會啟動binder機制(打開binder驅動肝集、映射內(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);
//在當前線程運行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衙荐,強轉為IServiceManager(本質(zhì)是BpServiceManager)
gDefaultServiceManager = interface_cast<IServiceManager>(
ProcessState::self()->getContextObject(NULL));
//如果IServiceManager還是null捞挥,則休眠1秒再取,直至取到才結束循環(huán)
if (gDefaultServiceManager == NULL)
sleep(1);
}
}
return gDefaultServiceManager;
}
因為SurfaceFlinger進程和ServiceManager進程都是init進程啟動的忧吟,有可能SurfaceFlinger在獲取IServiceManager時砌函,ServiceManager還沒來得及注冊,所以這里會邊取邊休眠溜族,取到才結束循環(huán)讹俊。
得到IServiceManager后,執(zhí)行sm->addService煌抒,在IServiceManager.cpp文件里有個BpServiceManager類仍劈,
//class BpServiceManager : public BpInterface<IServiceManager>
//這里的BpInterface是binder內(nèi)部的細節(jié)了,不是很理解寡壮,后面抽時間看看
//注冊系統(tǒng)服務(的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進程解析init.rc配置fork出新的進程况既,啟動多項獨立進程的系統(tǒng)服務这溅,如SurfaceFlinger
- 執(zhí)行SurfaceFlinger的可執(zhí)行程序,找到ServiceManager進程的BpServiceManager對象
- 通過BpServiceManager執(zhí)行addService注冊服務
非獨立進程的服務
非獨立進程的系統(tǒng)服務由SystemServer進程啟動棒仍,從圖解Android系統(tǒng)的啟動一文可知悲靴,SystemServer借助SystemServiceManager類(SSM)來啟動系統(tǒng)服務,比如AMS降狠,
//SystemServer.java
private void startBootstrapServices() {
//AMS由SSM創(chuàng)建啟動
mActivityManagerService = mSystemServiceManager
//創(chuàng)建并啟動AMS服務
.startService(ActivityManagerService.Lifecycle.class)
//通過binder獲取AMS服務
.getService();
//注冊AMS
mActivityManagerService.setSystemProcess();
}
//ActivityManagerService.java
public void setSystemProcess() {
//注冊AMS
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
}
調(diào)用了ServiceManager.addService()進行注冊庇楞,
//ServiceManager.java
public static void addService(String name, IBinder service, boolean allowIsolated) {
//跟前邊一樣,通過binder跨進程通信否纬,拿到ServiceManager進程的BpServiceManager對象
//調(diào)用BpServiceManager的addService
getIServiceManager().addService(name, service, allowIsolated);
}
可見吕晌,無論是SystemServer進程啟動的服務,還是init進程啟動的運行在獨立進程里的服務临燃,最終都是走ServiceManager進程的BpServiceManager.addService進行集中注冊睛驳。
總結
綜上,不管是由init進程啟動的獨立進程的系統(tǒng)服務如SurfaceFlinger膜廊,還是由SystemServer進程啟動的非獨立進程的系統(tǒng)服務如AMS乏沸,都是在ServiceManager進程中完成注冊和獲取的,在跨進程通信上使用了Android的binder機制爪瓜。
不過哈迪在工作中沒怎么用過binder蹬跃,所以他的內(nèi)部細節(jié)就暫時不深入了,后面抽時間再看铆铆。
再回顧一下~
系列文章: