圖解 | 一圖摸清Android系統(tǒng)服務(wù)

一圖摸清Android系統(tǒng)服務(wù)的獲取和注冊流程~

大綱:

  • 獲取系統(tǒng)服務(wù)
  • 注冊系統(tǒng)服務(wù)
    • 獨立進(jìn)程的服務(wù)
    • 非獨立進(jìn)程的服務(wù)
  • 總結(jié)
  • 參考資料

本文約1.9k字,閱讀大約8分鐘。

Android源碼基于8.0。

先預(yù)覽下整體流程~

image

開始分析!

獲取系統(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ù)的獲取過程:

  1. 應(yīng)用程序進(jìn)程調(diào)用getSystemService
  2. 通過binder跨進(jìn)程通信,拿到ServiceManager進(jìn)程的BpServiceManager對象
  3. 通過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;
}

梳理一下:

  1. init進(jìn)程解析init.rc配置fork出新的進(jìn)程啟動多項獨立進(jìn)程的系統(tǒng)服務(wù),如SurfaceFlinger
  2. 執(zhí)行SurfaceFlinger的可執(zhí)行程序,找到ServiceManager進(jìn)程的BpServiceManager對象
  3. 通過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,

//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é)就暫時不深入了,后面抽時間再看。

再回顧一下~

image

系列文章:

參考資料


更多性感文章,關(guān)注原創(chuàng)技術(shù)公眾號:哈利迪ei

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容