SystemServer啓動流程

在 zygote 啓動流程分析中,zygote最後會調用 SystemServer 的main函數,這篇就來介紹SystemServer的流程java

時序圖

SystemServer介紹

SystemServer 有點CPU的感受,咱們應用層用到的不少服務都是運行在該進程中的,好比WMS,AMS,PMSandroid

入口main函數

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

    private void run() {
        try {
            ......

            // Prepare the main looper thread (this thread).
            android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
            //主線程looper就在當前線程運行
            Looper.prepareMainLooper();

            //加載android_servers.so庫,該庫包含的源碼在frameworks/base/services/目錄下
            System.loadLibrary("android_servers");

            //檢測上次關機過程是否失敗,該方法可能不會返回
            performPendingShutdown();

            //初始化系統上下文 
            createSystemContext();

            //建立系統服務管理
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            // Prepare the thread pool for init tasks that can be parallelized
            SystemServerInitThreadPool.get();
        } finally {
            traceEnd();  // InitBeforeStartServices
        }

        //啓動各類系統服務
        try {
            traceBeginAndSlog("StartServices");
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            ......
        } finally {
            traceEnd();
        }
        // Loop forever. 一直處於循環狀態
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
複製代碼

createSystemContext

該過程會建立對象有ActivityThread,Instrumentation, ContextImpl,LoadedApk,Applicationgit

startBootstrapServices

private void startBootstrapServices() {
    //阻塞等待與installd創建socket通道
    Installer installer = mSystemServiceManager.startService(Installer.class);

    //啓動服務ActivityManagerService
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);

    //啓動服務PowerManagerService
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

    ......

    //啓動服務PackageManagerService
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    mFirstBoot = mPackageManagerService.isFirstBoot();
    mPackageManager = mSystemContext.getPackageManager();

    //啓動服務UserManagerService,新建目錄/data/user/
    ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());

    AttributeCache.init(mSystemContext);

    //設置AMS
    mActivityManagerService.setSystemProcess();

    //啓動傳感器服務
    startSensorService();
}
複製代碼

該方法所建立的服務:app

  • ActivityManagerService
  • PowerManagerService
  • LightsService
  • DisplayManagerService
  • PackageManagerService
  • UserManagerService
  • SensorService

startCoreServices

private void startCoreServices() {
    //啓動服務BatteryService,用於統計電池電量,須要LightService.
    mSystemServiceManager.startService(BatteryService.class);

    //啓動服務UsageStatsService,用於統計應用使用狀況
    mSystemServiceManager.startService(UsageStatsService.class);
    mActivityManagerService.setUsageStatsManager(
            LocalServices.getService(UsageStatsManagerInternal.class));

    mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();

    //啓動服務WebViewUpdateService
    mSystemServiceManager.startService(WebViewUpdateService.class);
}
複製代碼

經過傳入的類名進行實例化後添加到 mServices 中並調用自身的 onStartsocket

public void startService(@NonNull final SystemService service) {
        // Register it.
        mServices.add(service);
        // Start it.
        long time = SystemClock.elapsedRealtime();
        try {
            service.onStart();
        } catch (RuntimeException ex) {
            ......
        }
        warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
    }
複製代碼

該方法所建立的服務:ide

  • BatteryService
  • UsageStatsService
  • WebViewUpdateService

startOtherServices

// 和SettingsProvider關聯
mActivityManagerService.installSystemProviders();
// 設置對象關聯
mActivityManagerService.setWindowManager(wm);
......

// 準備好window, power, package, display服務
wm.systemReady();
mPowerManagerService.systemReady(...);
mPackageManagerService.systemReady();
mDisplayManagerService.systemReady(...);
        
mActivityManagerService.systemReady(new Runnable() {
    public void run() {
        ......
    }
});
複製代碼

AMS.systemReady

在服務啓動完畢後,會調用各個服務的 systemReady函數

AMS是最後一個啓動的服務,會調用 mActivityManagerService.systemReadyoop

mActivityManagerService.systemReady(new Runnable() {
    public void run() {
        //啓動WebView
      WebViewFactory.prepareWebViewInSystemServer();
      //啓動系統UI
      startSystemUi(context);

      // 執行一系列服務的systemReady方法
      networkScoreF.systemReady();
      networkManagementF.systemReady();
      networkStatsF.systemReady();

      ......

      //執行一系列服務的systemRunning方法
      wallpaper.systemRunning();
      inputMethodManager.systemRunning(statusBarF);
      location.systemRunning();

    }
});
複製代碼

這個函數裏進行了大量的systemRunning調用,主要是註冊廣播等等ui

好比 TelephonyRegistrythis

try {
    if (telephonyRegistryF != null) telephonyRegistryF.systemRunning();
    } catch (Throwable e) {
        reportWtf("Notifying TelephonyRegistry running", e);
    }

    public void systemRunning() {
        // Watch for interesting updates
        final IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_USER_SWITCHED);
        filter.addAction(Intent.ACTION_USER_REMOVED);
        filter.addAction(TelephonyIntents.ACTION_DEFAULT_SUBSCRIPTION_CHANGED);
        log("systemRunning register for intents");
        mContext.registerReceiver(mBroadcastReceiver, filter);
}
複製代碼

startSystemUi

static final void startSystemUi(Context context) {
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("com.android.systemui",
                "com.android.systemui.SystemUIService"));
    context.startServiceAsUser(intent, UserHandle.OWNER);
}
複製代碼

該函數的主要做用是啓動服務 」com.android.systemui.SystemUIService」

AMS簡單流程

這裏須要介紹下AMS的流程,由於後續的代碼就是和AMS有關了

在前面 startBootstrapServices 的流程中有一段代碼

ams.setSystemProcess()

在 startOtherServices 中有段代碼

ams.installSystemProviders()

這些都是AMS的大體流程

  • 建立AMS對象
  • 調用ams.setSystemProcess
  • 調用ams.installSystemProviders
  • 調用ams.systemReady

在 systemReady 的最後它會調用到 ams 中的 startHomeActivityLocked 函數,他的主要做用就是啓動桌面Activity

boolean startHomeActivityLocked(int userId, String reason) {
    //home intent有CATEGORY_HOME
    Intent intent = getHomeIntent();
    ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
    if (aInfo != null) {
        intent.setComponent(new ComponentName(
                aInfo.applicationInfo.packageName, aInfo.name));
        aInfo = new ActivityInfo(aInfo);
        aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
        ProcessRecord app = getProcessRecordLocked(aInfo.processName,
                aInfo.applicationInfo.uid, true);
        if (app == null || app.instrumentationClass == null) {
            intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
            //啓動桌面Activity
            mStackSupervisor.startHomeActivity(intent, aInfo, reason);
        }
    }
    return true;
}
複製代碼

systemReady大體流程

public final class ActivityManagerService{

    public void systemReady(final Runnable goingCallback) {
        ...//更新操做
        mSystemReady = true; //系統處於ready狀態
        removeProcessLocked(proc, true, false, "system update done");//殺掉全部非persistent進程
        mProcessesReady = true;  //進程處於ready狀態

        goingCallback.run(); //這裏有可能啓動進程

        addAppLocked(info, false, null); //啓動全部的persistent進程
        mBooting = true;  //正在啓動中
        startHomeActivityLocked(mCurrentUserId, "systemReady"); //啓動桌面
        mStackSupervisor.resumeTopActivitiesLocked(); //恢復棧頂的Activity
    }
}
複製代碼

參考博客 Android系統啓動-SystemServer

相關文章
相關標籤/搜索