Android Framework 之 SystemServer

閱讀須知

本文源碼基于 Android 10

Questions

  1. 如何處理系統(tǒng)服務(wù)啟動的依賴關(guān)系?
  2. 如何發(fā)布系統(tǒng)服務(wù),讓其對其他應(yīng)用或服務(wù)可見?

SystemServer

Zygote 一文中簡單的提到了 Zygote 啟動后會去啟動 SystemServer。本文將從源碼的角度對 SystemServer 做一個詳細(xì)的分析。

本文的大致流程如下圖所示。

image.png

啟動 SystemServer

首先看看 SystemServer 的啟動。這里主要做了如下事情:

  1. Zygote 設(shè)置 SigChld 信號處理;
  2. 通過 fork() 孵化出 system_server
image.png

還記得 ZygoteInit.main() 里啟動 SystemServer 的代碼嗎?

// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {
    Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
    if (r != null) {
        r.run();
        return;
    }
}

private static Runnable forkSystemServer(String abiList, String socketName,
        ZygoteServer zygoteServer) {
    // 參數(shù)組裝
    String args[] = {
        // ...
        "com.android.server.SystemServer",
    };
    ZygoteArguments parsedArgs = null;
    parsedArgs = new ZygoteArguments(args);
    // 啟動 system_server 進(jìn)程
    pid = Zygote.forkSystemServer(
            parsedArgs.mUid, parsedArgs.mGid,
            parsedArgs.mGids,
            parsedArgs.mRuntimeFlags,
            null,
            parsedArgs.mPermittedCapabilities,
            parsedArgs.mEffectiveCapabilities);
}

注意這里啟動 SystemServer 傳遞的參數(shù) com.android.server.SystemServer,后面會用到。這里的調(diào)用鏈如下圖所示。

image.png

設(shè)置 SigChld 信號處理

ForkCommon() 中首先會給 Zygote 設(shè)置 SigChld 信號處理。

// frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
                        const std::vector<int>& fds_to_close,
                        const std::vector<int>& fds_to_ignore) {
  // 設(shè)置 SigChld 信號處理
  SetSignalHandlers();
}

static void SetSignalHandlers() {
  struct sigaction sig_chld = {};
  // 當(dāng)收到 SigChld 信號的時候調(diào)用 SigChldHandler
  sig_chld.sa_handler = SigChldHandler;
}

static void SigChldHandler(int /*signal_number*/) {
  while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
    // 當(dāng) system_server 進(jìn)程掛掉了,則把 zygote 干掉,讓 init 去重啟 zygote
    if (pid == gSystemServerPid) {
      kill(getpid(), SIGKILL);
    }
  }
}

當(dāng) system_server 掛掉時 Zygote 會收到 SigChld 信號,然后 Zygotekill 自身,讓 init 來重啟 Zygote

這里的 gSystemServerPidsystem_serverpid,它是在 ForkCommon() 調(diào)用后賦值的。

// frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

static jint com_android_internal_os_Zygote_nativeForkSystemServer(
        JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
        jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
        jlong effective_capabilities) {  
  // 這里調(diào)用的 FormCommon()
  pid_t pid = ForkCommon(env, true,
                         fds_to_close,
                         fds_to_ignore);
  if (pid == 0) {
      // pid == 0 表示在 system_server 進(jìn)程
  } else if (pid > 0) {
      // pid > 0 表示在父進(jìn)程,這里 gSystemServerPid 賦值為 system_server 的進(jìn)程id
      gSystemServerPid = pid;
  }
  return pid;
}

孵化 system_server 進(jìn)程

設(shè)置完 SigChld 信號處理后,就通過 fork() 孵化 system_server 進(jìn)程。

// frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
                        const std::vector<int>& fds_to_close,
                        const std::vector<int>& fds_to_ignore) {
  // fork system_server 進(jìn)程
  pid_t pid = fork();
}

關(guān)于 fork(),這里簡單說明一下,它被調(diào)用一次,會返回兩次,有 3 種不同的返回值:

  • 在父進(jìn)程中,fork() 返回子進(jìn)程的 pid
  • 在子進(jìn)程中,fork() 返回 0;
  • 當(dāng) fork 子進(jìn)程報錯時返回負(fù)值。

因?yàn)楫?dāng)進(jìn)程調(diào)用 fork() 后,控制轉(zhuǎn)移到內(nèi)核中的 fork() 代碼,內(nèi)核會做 4 件事情:

  1. 分配新的內(nèi)存塊和內(nèi)核數(shù)據(jù)結(jié)構(gòu)給子進(jìn)程;
  2. 將父進(jìn)程部分?jǐn)?shù)據(jù)結(jié)構(gòu)內(nèi)容拷貝至子進(jìn)程;
  3. 添加子進(jìn)程到系統(tǒng)進(jìn)程列表當(dāng)中;
  4. fork() 返回,開始調(diào)度器調(diào)度。

所以當(dāng)程序執(zhí)行 pid = fork() 時,由于在復(fù)制時子進(jìn)程復(fù)制了父進(jìn)程的堆棧段或相應(yīng)的變量與數(shù)據(jù)結(jié)構(gòu),所以兩個進(jìn)程都停留在 fork() 中,等待返回。

因此 fork() 會返回兩次,一次是在父進(jìn)程中返回,另一次是在子進(jìn)程中返回,這兩次的返回值是不一樣的。

準(zhǔn)備工作

forksystem_server 后,會做一些初始化工作。主要包括:

  1. 一些常規(guī)的初始化,然后啟動 binder 線程;
  2. 查找并調(diào)用 SystemServer.main()
image.png

回到 ZygoteInit 接著 forkSystemServer() 往下看。

// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
    // fork system_server
    pid = Zygote.forkSystemServer(
                    parsedArgs.mUid, parsedArgs.mGid,
                    parsedArgs.mGids,
                    parsedArgs.mRuntimeFlags,
                    null,
                    parsedArgs.mPermittedCapabilities,
                    parsedArgs.mEffectiveCapabilities);
    // pid == 0 表示在 system_server 進(jìn)程
    if (pid == 0) {
        // 調(diào)用 handleSystemServerProcess 做一些初始化工作
        return handleSystemServerProcess(parsedArgs);
    }
}

這里 pid == 0 即在 system_server 進(jìn)程,其調(diào)用鏈如下圖紅框所示。

image.png

啟動 binder 線程

zygoteInit() 中會先做一些常規(guī)的初始化操作,然后開啟 binder 線程。

// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
    ZygoteInit.nativeZygoteInit();
}

// frameworks/base/core/jni/AndroidRuntime.cpp

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    // gCurRuntime 即 AppRuntime
    gCurRuntime->onZygoteInit();
}

// frameworks/base/cmds/app_process/app_main.cpp

virtual void onZygoteInit()
{
    sp<ProcessState> proc = ProcessState::self();
    // 開啟 binder 線程
    proc->startThreadPool();
}

這里的 gCurRuntime 就是 AppRuntime,它是在 Zygote 的入口函數(shù) app_main.main() 被賦值的。

// frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, char* const argv[])
{
    // AppRuntime 繼承了 AndroidRuntime
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
}

// frameworks/base/core/jni/AndroidRuntime.cpp

AndroidRuntime::AndroidRuntime(char* argBlockStart, const size_t argBlockLength) :
        mExitWithoutCleanup(false),
        mArgBlockStart(argBlockStart),
        mArgBlockLength(argBlockLength)
{
    // 在 AndroidRuntime 構(gòu)造器里面會將 gCurRuntime 賦值為 AppRuntime
    gCurRuntime = this;
}

查找并調(diào)用 SystemServer.main()

啟動 binder 線程后,緊接著會去查找并調(diào)用 com.android.server.SystemServer (前面提到過的參數(shù))的 static main()

// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
    return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

// frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

protected static Runnable findStaticMain(String className, String[] argv,
    ClassLoader classLoader) {
    Class<?> cl;

    try {
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
    }

    // 反射查找 main()
    Method m;
    try {
        m = cl.getMethod("main", new Class[] { String[].class });
    } catch (NoSuchMethodException ex) {
    } catch (SecurityException ex) {
    }

    // 判斷是不是 public static
    int modifiers = m.getModifiers();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
        throw new RuntimeException(
                "Main method is not public and static on " + className);
    }

    return new MethodAndArgsCaller(m, argv);
}

static class MethodAndArgsCaller implements Runnable {

    public void run() {
        try {
            // 調(diào)用 main()
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
        } catch (InvocationTargetException ex) {
        }
    }
}

SystemServer工作流程

進(jìn)入 SystemServer.main() 后就開始 SystemServer 的工作流程了。這里主要會做如下事情:

  1. 初始化主線程 Looper
  2. 加載 android_servers.so 庫;
  3. 初始化系統(tǒng)上下文;
  4. 創(chuàng)建系統(tǒng)服務(wù)管理者 SystemServiceManager
  5. 分批次分階段性的啟動服務(wù);
  6. 進(jìn)入 loop() 循環(huán)等待和處理請求。
image.png

SystemServer.main() 簡單粗暴,直接創(chuàng)建 SystemServer,然后調(diào)用其 run()

// frameworks/base/services/java/com/android/server/SystemServer.java

public static void main(String[] args) {
    new SystemServer().run();
}

初始化主線程 Looper

首先會初始化主線程 Looper

// frameworks/base/services/java/com/android/server/SystemServer.java

private void run() {
    Looper.prepareMainLooper();
}

加載 android_servers.so

接著加載 android_servers.so 庫,該庫包含的源碼位于 frameworks/base/services/core/jni 下。

// frameworks/base/services/java/com/android/server/SystemServer.java

private void run() {
    System.loadLibrary("android_servers");
}

初始化系統(tǒng)上下文

接著會初始化系統(tǒng)上下文。

// frameworks/base/services/java/com/android/server/SystemServer.java

private void run() {
    createSystemContext();
}

其調(diào)用鏈如下圖所示,它和應(yīng)用進(jìn)程類似,也會創(chuàng)建 ActivityThread,調(diào)用其 attach(),創(chuàng)建 Application 等。

image.png

構(gòu)建包名為 android 的 LoadedApk

這里主要看下 ContextImpl.createSystemContext()

// frameworks/base/core/java/android/app/ContextImpl.java

static ContextImpl createSystemContext(ActivityThread mainThread) {
    // 構(gòu)建包名為 android 的 LoadedApk
    LoadedApk packageInfo = new LoadedApk(mainThread);
    // 構(gòu)建 ContextImpl
    ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
            null, null);
    return context;
}

// frameworks/base/core/java/android/app/LoadedApk.java

LoadedApk(ActivityThread activityThread) {
    mActivityThread = activityThread;
    mApplicationInfo = new ApplicationInfo();
    // 包名為 android
    mApplicationInfo.packageName = "android";
    mPackageName = "android";
}

可以看到這里構(gòu)建了一個包名為 androidLoadedApk

構(gòu)建 Resources

接著會創(chuàng)建 ResourcesImpl

// frameworks/base/core/java/android/app/LoadedApk.java

LoadedApk(ActivityThread activityThread) {
    mResources = Resources.getSystem();
}

// frameworks/base/core/java/android/content/res/Resources.java

private Resources() {
    // 創(chuàng)建 ResourceImpl,并調(diào)用 AssetManager.getSystem()
    mResourcesImpl = new ResourcesImpl(AssetManager.getSystem(), metrics, config,
            new DisplayAdjustments());
}

加載 framework-res.apk

在創(chuàng)建 ResourceImpl 時調(diào)用了 AssetManager.getSystem(),這里會加載 framework-res.apk,并創(chuàng)建 AssetManager

// frameworks/base/core/java/android/content/res/AssetManager.java

// frameowrk-res.apk 路徑
private static final String FRAMEWORK_APK_PATH = "/system/framework/framework-res.apk";

static AssetManager sSystem = null;

public static AssetManager getSystem() {
    synchronized (sSync) {
        // 這里會加載 framework-res.apk
        createSystemAssetsInZygoteLocked();
        return sSystem;
    }
}

private static void createSystemAssetsInZygoteLocked() {
    final ArrayList<ApkAssets> apkAssets = new ArrayList<>();
    // 加載 framework-res.apk
    apkAssets.add(ApkAssets.loadFromPath(FRAMEWORK_APK_PATH, true /*system*/));
    sSystemApkAssets = apkAssets.toArray(new ApkAssets[apkAssets.size()]);
    // 創(chuàng)建 AssetManager
    sSystem = new AssetManager(true /*sentinel*/);
    // 設(shè)置 apk 資源
    sSystem.setApkAssets(sSystemApkAssets, false /*invalidateCaches*/);
}

創(chuàng)建 SystemServiceManager

接著會創(chuàng)建 SystemServiceManager

// frameworks/base/services/java/com/android/server/SystemServer.java

private void run() {
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
}

SystemServiceManager

SystemServiceManager 是用來管理系統(tǒng)服務(wù)(繼承自 SystemService 的類)的創(chuàng)建、啟動和其他生命周期事件。

關(guān)于 SystemServiceManager 主要關(guān)注其兩個方法 startService()startBootPhase()

startService()

startService() 是用來創(chuàng)建系統(tǒng)服務(wù),并將系統(tǒng)服務(wù)添加到 mServices 集合中進(jìn)行統(tǒng)一的管理,最后調(diào)用系統(tǒng)服務(wù)的 onStart()

// frameworks/base/services/java/com/android/server/SystemService.java

// 對 SystemService 進(jìn)行統(tǒng)一的管理
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
    
public SystemService startService(String className) {
    final Class<SystemService> serviceClass;
    try {
        serviceClass = (Class<SystemService>)Class.forName(className);
    } catch (ClassNotFoundException ex) {
    }
    return startService(serviceClass);
}

public <T extends SystemService> T startService(Class<T> serviceClass) {
    final String name = serviceClass.getName();
    // 判斷是否是繼承自 SystemService
    if (!SystemService.class.isAssignableFrom(serviceClass)) {
        throw new RuntimeException("Failed to create " + name
                + ": service must extend " + SystemService.class.getName());
    }
    // 反射創(chuàng)建
    final T service;
    try {
        Constructor<T> constructor = serviceClass.getConstructor(Context.class);
        service = constructor.newInstance(mContext);
    } catch (InstantiationException ex) {
    } catch (IllegalAccessException ex) {
    } catch (NoSuchMethodException ex) {
    } catch (InvocationTargetException ex) {
    }

    startService(service);
    return service;
}

public void startService(@NonNull final SystemService service) {
    // 注冊服務(wù)
    mServices.add(service);
    // 調(diào)用其 onStart()
    service.onStart();
}
startBootPhase()

Android 系統(tǒng)的系統(tǒng)服務(wù)是非常之多的,這些系統(tǒng)服務(wù)之間或多或少會存在一些依賴關(guān)系,如何去保證這些系統(tǒng)服務(wù)都能夠正常有序的啟動就成了一個問題。SystemServer 通過分批分階段的方式來解決這個問題。

當(dāng)啟動到達(dá)不同階段的時候 SystemServer 會調(diào)用 startBootPhase(),這時 SystemServiceManager 就會通知已經(jīng)添加到 mServices 中系統(tǒng)服務(wù),這樣系統(tǒng)服務(wù)只需要在不同的階段做不同的事情即可。

// frameworks/base/services/java/com/android/server/SystemService.java

private int mCurrentPhase = -1;

public void startBootPhase(final int phase) {
    // 保存當(dāng)前所處階段
    if (phase <= mCurrentPhase) {
        throw new IllegalArgumentException("Next phase must be larger than previous");
    }
    mCurrentPhase = phase;

    try {
        // 遍歷 mServices 中的系統(tǒng)服務(wù)并調(diào)用其 onBootPhase()
        final int serviceLen = mServices.size();
        for (int i = 0; i < serviceLen; i++) {
            final SystemService service = mServices.get(i);
            try {
                service.onBootPhase(mCurrentPhase);
            } catch (Exception ex) {
            }
        }
    } finally {
    }
}

SystemService

SystemService 是系統(tǒng)服務(wù)的基類。

關(guān)于 SystemService 主要關(guān)注其幾個生命周期方法,onStart()publishBinderService()onBootPhase

onStart()

當(dāng)服務(wù)啟動后應(yīng)調(diào)用此方法,一般會在里面發(fā)布服務(wù)。

// frameworks/base/services/core/java/com/android/server/SystemService.java

public abstract void onStart();
publishBinderService()

publishBinderService() 用于發(fā)布服務(wù)。

系統(tǒng)服務(wù)通過此方法將自己的 IBinder 發(fā)布到 ServiceManager 中,這樣其他應(yīng)用或服務(wù)就可以訪問到它。

// frameworks/base/services/core/java/com/android/server/SystemService.java

protected final void publishBinderService(String name, IBinder service) {
    publishBinderService(name, service, false);
}

protected final void publishBinderService(String name, IBinder service,
        boolean allowIsolated) {
    publishBinderService(name, service, allowIsolated, DUMP_FLAG_PRIORITY_DEFAULT);
}

protected final void publishBinderService(String name, IBinder service,
        boolean allowIsolated, int dumpPriority) {
    ServiceManager.addService(name, service, allowIsolated, dumpPriority);
}
onBootPhase()

前面說了當(dāng)?shù)竭_(dá)不同階段時,SystemServer 會通過 SystemServiceManagerstartBootPhase() 來通知系統(tǒng)服務(wù),那系統(tǒng)服務(wù)可以通過重寫 onBootPhase() 來接受不同階段事件,并在所關(guān)心的階段處理對應(yīng)的事情。

// frameworks/base/services/core/java/com/android/server/SystemService.java

public abstract class SystemService {

    public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100;

    public static final int PHASE_LOCK_SETTINGS_READY = 480;
    
    public static final int PHASE_SYSTEM_SERVICES_READY = 500;

    public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520;

    public static final int PHASE_ACTIVITY_MANAGER_READY = 550;

    public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;
    
    public static final int PHASE_BOOT_COMPLETED = 1000;
    
    public void onBootPhase(int phase) {}
}

啟動服務(wù)

創(chuàng)建完 SystemServiceManager 后,就開始啟動服務(wù)。前面說過 SystemServer 通過分批分階段的方式來啟動服務(wù),系統(tǒng)服務(wù)被分為引導(dǎo)服務(wù)、核心服務(wù)和其他服務(wù)三批進(jìn)行啟動,分別對應(yīng) startBootstrapServices()startCoreServices()startOtherServices()

啟動引導(dǎo)服務(wù)

startBootstrapServices() 會啟動引導(dǎo)服務(wù),包括我們所熟知的 ActivityManagerServicePackageManagerService 等。

// frameworks/base/services/java/com/android/server/SystemServer.java

private void startBootstrapServices() {
    // 啟動 ActivityManagerService
    ActivityTaskManagerService atm = mSystemServiceManager.startService(
            ActivityTaskManagerService.Lifecycle.class).getService();
    mActivityManagerService = ActivityManagerService.Lifecycle.startService(
            mSystemServiceManager, atm);
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);

    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
    // 通知 SystemServiceManager 到了 PHASE_WAIT_FOR_DEFAULT_DISPLAY 階段
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);

    // 啟動 PackageManagerService
    try {
        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    } finally {
    }

    mActivityManagerService.setSystemProcess();
}

關(guān)于 ActivityManagerService 后面有文章做詳細(xì)的分析。

啟動核心服務(wù)

startCoreServices() 會啟動核心服務(wù),包括 BatteryServiceGpuService 等等。

// frameworks/base/services/java/com/android/server/SystemServer.java
private void startCoreServices() {
    // BatterService
    mSystemServiceManager.startService(BatteryService.class);
    
    // GpuService
    mSystemServiceManager.startService(GpuService.class);
}

啟動其他服務(wù)

startOtherServices() 會分階段啟動其他服務(wù),方法很長,感興趣的自行去研究。

// frameworks/base/services/java/com/android/server/SystemServer.java

private void startOtherServices() {
    // VibratorService
    vibrator = new VibratorService(context);
    ServiceManager.addService("vibrator", vibrator);

    // AlarmManagerService
    mSystemServiceManager.startService(new AlarmManagerService(context));

    inputManager = new InputManagerService(context);
    // WindowManagerService
    wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
            new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
    ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
            DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
    // InputManagerService
    ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
    mActivityManagerService.setWindowManager(wm);

    // AccessibilityManagerService
    try {
        mSystemServiceManager.startService(ACCESSIBILITY_MANAGER_SERVICE_CLASS);
    } catch (Throwable e) {
        reportWtf("starting Accessibility Manager", e);
    }

    // JobSchedulerService
    mSystemServiceManager.startService(JobSchedulerService.class);

    // 通知 SystemServiceManager 到達(dá) PHASE_LOCK_SETTINGS_READY 階段
    mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
    // 通知 SystemServiceManager 到達(dá) PHASE_SYSTEM_SERVICES_READY 階段
    mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);

    final Configuration config = wm.computeNewConfiguration(DEFAULT_DISPLAY);
    DisplayMetrics metrics = new DisplayMetrics();
    WindowManager w = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    w.getDefaultDisplay().getMetrics(metrics);
    context.getResources().updateConfiguration(config, metrics);

    mPackageManagerService.systemReady();

    // 通知 SystemServiceManager 到達(dá) PHASE_DEVICE_SPECIFIC_SERVICES_READY 階段
    mSystemServiceManager.startBootPhase(SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);

    // 調(diào)用 AMS 的 systemReady()
    mActivityManagerService.systemReady(() -> {
        // 通知 SystemServiceManager 到達(dá) PHASE_ACTIVITY_MANAGER_READY 階段
        mSystemServiceManager.startBootPhase(
                    SystemService.PHASE_ACTIVITY_MANAGER_READY);
    }

    // 通知 SystemServiceManager 到達(dá) PHASE_THIRD_PARTY_APPS_CAN_START 階段
    mSystemServiceManager.startBootPhase(
        SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
}

進(jìn)入 loop() 循環(huán)

最后會調(diào)用主線程 Looperloop() 進(jìn)入循環(huán)等待處理請求。

// frameworks/base/services/java/com/android/server/SystemServer.java

private void run() {
    Looper.loop();
}

Answers

至此 SystemServer 就分析完了,接下來回過頭看看前面的問題。

如何處理系統(tǒng)服務(wù)啟動的依賴關(guān)系?

SystemServer 通過分批分階段的方式來啟動 ServiceManager
分批是指將系統(tǒng)服務(wù)分為三批:

  1. 啟動引導(dǎo)服務(wù),startBootstrapServices()
  2. 啟動核心服務(wù),startCoreServices()
  3. 啟動其他服務(wù),startOtherServices()

分階段是 SystemServer 在不同的階段會通過 startBootPhase() 通知 SystemServiceManager,進(jìn)而通過 onBootPhase() 通知系統(tǒng)服務(wù)。

如何發(fā)布系統(tǒng)服務(wù),讓其對其他應(yīng)用或服務(wù)可見?

發(fā)布服務(wù)最終是通過 ServiceManageraddService()

繼承自 SystemService 的系統(tǒng)服務(wù)可以在 onStart() 中通過 publishBinderService() 發(fā)布服務(wù),其底層還是調(diào)用的 ServiceManageraddService()

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內(nèi)容