Android系統啟動-SystemServer下篇

co518248 10年前發布 | 22K 次閱讀 安卓開發 Android開發 移動開發

基于Android 6.0的源碼剖析, 分析Android啟動過程的system_server進程

frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/core/java/android/app/LoadedApk.java
frameworks/base/core/java/android/app/ContextImpl.java
frameworks/base/core/java/com/android/server/LocalServices.java
frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
frameworks/base/services/core/java/com/android/server/ServiceThread.java
frameworks/base/services/core/java/com/android/server/pm/Installer.java
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

一、啟動調用棧

System_server啟動函數調用類的棧關系:

SystemServer.main
    SystemServer.run
        createSystemContext
            ActivityThread.systemMain
                ActivityThread.attach
                    LoadedApk.makeApplication
            ActivityThread.getSystemContext
                ContextImpl.createSystemContext
        startBootstrapServices(); 
        startCoreServices();    
        startOtherServices();
        Looper.loop();

二、 SystemServer分析

上一篇文章 Android系統啟動-systemServer上篇 講解了從Zygote一路啟動到SystemServer的過程,本文重要是講述system_server所承載的java framework的系統服務框架,是如何一路路啟動的。

Step 1.SystemServer.main

public static void main(String[] args) {
    //先初始化SystemServer對象,再調用對象的run()方法, 【見Step 2】
    new SystemServer().run(); 
}

Step 2.SystemServer.run

private void run() {
    //當系統時間比1970年更早,就設置當前系統時間為1970年
    if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
        SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
    }

    //變更虛擬機的庫文件,對于Android 6.0默認采用的是libart.so
    SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

    //isEnabled()為true,則開啟采用分析器
    if (SamplingProfilerIntegration.isEnabled()) {
        SamplingProfilerIntegration.start();
        mProfilerSnapshotTimer = new Timer();
        //system_server每隔1小時采用一次,并保存結果到system_server文件
        mProfilerSnapshotTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                SamplingProfilerIntegration.writeSnapshot("system_server", null);
            }
        }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
    }

    //清除vm內存增長上限,由于啟動過程需要較多的虛擬機內存空間
    VMRuntime.getRuntime().clearGrowthLimit();

    //設置內存的可能有效使用率為0.8
    VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
    // 針對部分設備依賴于運行時就產生指紋信息,因此需要在開機完成前已經定義
    Build.ensureFingerprintProperty();

    //訪問環境變量前,需要明確地指定用戶
    Environment.setUserRequired(true);

    //確保當前系統進程的binder調用,總是運行在前臺優先級(foreground priority)
    BinderInternal.disableBackgroundScheduling(true);
    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();

    //初始化系統上下文 【見Step 3】
    createSystemContext();

    //創建系統服務管理
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    //將mSystemServiceManager添加到本地服務的成員sLocalServiceObjects
    LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);


    //啟動各種系統服務
    try {
        startBootstrapServices(); // 啟動引導服務【見Step 4】
        startCoreServices();      // 啟動核心服務【見Step 5】
        startOtherServices();     // 啟動其他服務【見Step 6】
    } catch (Throwable ex) {
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    }

    //用于debug版本,將log事件不斷循環地輸出到dropbox(用于分析)
    if (StrictMode.conditionallyEnableDebugLogging()) {
        Slog.i(TAG, "Enabled StrictMode for system server main thread.");
    }
    //一直循環執行
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

LocalServices通過用靜態Map變量sLocalServiceObjects,來保存以服務類名為key,以具體服務對象為value的Map結構。

Step 3.SystemServer.createSystemContext

private void createSystemContext() {
    //創建ActivityThread對象【見Step 3-1】
    ActivityThread activityThread = ActivityThread.systemMain();
    //創建ContextImpl、LoadedApk對象【見Step 3-2】
    mSystemContext = activityThread.getSystemContext();
    //設置主題
    mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
}

Step 3-1.ActivityThread.systemMain

public static ActivityThread systemMain() {
    //對于低內存的設備,禁用硬件加速
    if (!ActivityManager.isHighEndGfx()) {
        HardwareRenderer.disable(true);
    } else {
        HardwareRenderer.enableForegroundTrimming();
    }
    // 創建ActivityThread
    ActivityThread thread = new ActivityThread();
    // 創建Application以及調用其onCreate()方法【見Step 3-1-1】
    thread.attach(true);
    return thread;
}

Step 3-1-1.ActivityThread.attach

private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;

    if (!system) {
    ...

    } else {
        //system=true,進入此分支
        android.ddm.DdmHandleAppName.setAppName("system_process",
                UserHandle.myUserId());
        try {
            mInstrumentation = new Instrumentation();
            // 創建應用上下文
            ContextImpl context = ContextImpl.createAppContext(
                    this, getSystemContext().mPackageInfo);
            //創建Application 【見Step 3-1-1-1】
            mInitialApplication = context.mPackageInfo.makeApplication(true, null);
            //調用Application.onCreate()方法
            mInitialApplication.onCreate();
        } catch (Exception e) {
            throw new RuntimeException(
                    "Unable to instantiate Application():" + e.toString(), e);
        }
    }

    //添加dropbox log信息到libcore
    DropBox.setReporter(new DropBoxReporter());

    // 設置回調方法
    ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            synchronized (mResourcesManager) {
                if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {
                    if (mPendingConfiguration == null ||
                            mPendingConfiguration.isOtherSeqNewer(newConfig)) {
                        mPendingConfiguration = newConfig;

                        sendMessage(H.CONFIGURATION_CHANGED, newConfig);
                    }
                }
            }
        }
        @Override
        public void onLowMemory() {
        }
        @Override
        public void onTrimMemory(int level) {
        }
    });
}

主要工作是創建應用上下文ContextImpl,創建Application以及調用其onCreate()方法,設置DropBox以及ComponentCallbacks2回調方法。

Step 3-1-1-1.LoadedApk.makeApplication

public Application makeApplication(boolean forceDefaultAppClass,
        Instrumentation instrumentation) {
    if (mApplication != null) {
        return mApplication;
    }

    Application app = null;

    String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) {
        appClass = "android.app.Application"; //設置class名
    }

    try {
        java.lang.ClassLoader cl = getClassLoader();
        if (!mPackageName.equals("android")) {
            initializeJavaContextClassLoader(); //不進入該分支
        }
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        // 創建Application
        app = mActivityThread.mInstrumentation.newApplication(
                cl, appClass, appContext);
        appContext.setOuterContext(app);
    } catch (Exception e) {
        ...
    }
    // 將前面創建的app添加到應用列表。
    mActivityThread.mAllApplications.add(app);
    mApplication = app;
    ...

    return app;
}

在該方法調用之前,已經創建了LoadedApk對象,該對象的成員變量mPackageName=”android”; mClassLoader = ClassLoader.getSystemClassLoader();

Step 3-2.ActivityThread.getSystemContext

public ContextImpl getSystemContext() {
    synchronized (this) {
        if (mSystemContext == null) {
            //創建ContextImpl對象【見Step 3-2-1】
            mSystemContext = ContextImpl.createSystemContext(this);
        }
        return mSystemContext;
    }
}

Step 3-2-1.ContextImpl.createSystemContext

static ContextImpl createSystemContext(ActivityThread mainThread) {
    //創建LoadedApk對象
    LoadedApk packageInfo = new LoadedApk(mainThread);
    //創建ContextImpl對象
    ContextImpl context = new ContextImpl(null, mainThread,
            packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);
    context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), 
            context.mResourcesManager.getDisplayMetricsLocked());
    return context;
}

運行到這里,system_server的準備環境基本完成,接下來開始system_server中最為核心的過程,啟動系統服務。 通過 startBootstrapServices() , startCoreServices() , startOtherServices() 3個方法。

Step 4.startBootstrapServices

[–>SystemServer.java]

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);

    //初始化power management
    mActivityManagerService.initPowerManagement();

    //啟動服務LightsService 
    mSystemServiceManager.startService(LightsService.class);

    //啟動服務DisplayManagerService
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

    //在初始化package manager之前,需要默認的顯示
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);

    //當設備正在加密時,僅運行核心
    String cryptState = SystemProperties.get("vold.decrypt");
    if (ENCRYPTING_STATE.equals(cryptState)) {
        mOnlyCore = true;
    } else if (ENCRYPTED_STATE.equals(cryptState)) {
        mOnlyCore = true;
    }

    //啟動服務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();
}

該方法所創建的服務:ActivityManagerService, PowerManagerService, LightsService, DisplayManagerService, PackageManagerService, UserManagerService, sensor服務.

Step 5.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);
}

啟動服務BatteryService,UsageStatsService,WebViewUpdateService。

Step 6.startOtherServices

該方法比較長,有近千行代碼,邏輯很簡單,主要是啟動一系列的服務,這里就不列舉源碼了,在第四節直接對其中的服務進行一個簡單分類。

三、Service啟動過程

接下來,開始正式進入啟動系統服務的過程。

啟動方式

system_server進程中的服務啟動方式有兩種,

  1. 一種是通過SystemServiceManager的 startService() ,該方法用于啟動繼承于SystemService的服務。主要功能:創建serviceClass類的對象,將剛創建對象添加到SystemServiceManager的成員變量mServices,再調用剛創建對象的onStart()方法。對于服務啟動到一定階段,進入相應的Phase時,會調用SystemServiceManager的 startBootPhase() 回調方法,該方法會循環遍歷所有向 SystemServiceManager 注冊過的service的 onBootPhase() 方法。
  2. 另一種是通過ServiceManager的 addService(String name, IBinder service) ,該方法用于初始化繼承于IBinder的服務。主要功能將該服務向Native層的 service Manager注冊服務

啟動流程

SystemServiceManager的 startBootPhase() 方法貫穿整個階段,啟動階段從 PHASE_WAIT_FOR_DEFAULT_DISPLAY 到 PHASE_BOOT_COMPLETED ,如下圖:

啟動流程分析:

  1. PHASE_WAIT_FOR_DEFAULT_DISPLAY=100 ,該階段等待Display有默認顯示;
  2. PHASE_LOCK_SETTINGS_READY=480 ,進入該階段服務能獲取鎖屏設置的數據;
  3. PHASE_SYSTEM_SERVICES_READY=500 ,進入該階段服務能安全地調用核心系統服務,如PMS;
  4. PHASE_ACTIVITY_MANAGER_READY=550 ,進入該階段服務能廣播Intent;
  5. PHASE_THIRD_PARTY_APPS_CAN_START=600 ,進入該階段服務能start/bind第三方apps,app能通過BInder調用service;
  6. PHASE_BOOT_COMPLETED=1000 ,該階段是發生在Boot完成和home應用啟動完畢。系統服務更傾向于監聽該階段,而不是注冊廣播ACTION_BOOT_COMPLETED,從而降低系統延遲。

Phase 100

創建ActivityManagerService、PowerManagerService、LightsService、DisplayManagerService共4項服務;

接著則進入階段 100 ,該階段調用DisplayManagerService的 onBootPhase() 方法。

Phase 480&&500

創建PackageManagerService、WindowManagerService、InputManagerService、NetworkManagerService、DropBoxManagerService/FingerprintService等服務

接著則進入階段 480 ,該階段調用DevicePolicyManagerService的 onBootPhase() 方法; 緊接著進入階段 500 ,實現該階段的回調方法的服務較多。

Phase 550

WindowManagerService、PowerManagerService、PackageManagerService、DisplayManagerService分別依次執行 systemReady() 方法;然后ActivityManagerService進入 systemReady() 方法;

接著則進入階段 550 ,實現該階段的回調方法的服務較多。

Phase 600

AMS啟動native crash監控,,加載WebView,啟動SystemUi;然后是NetworkScoreService、NetworkManagementService、NetworkStatsService、NetworkPolicyManagerService、ConnectivityService、AudioService分別依次執行 systemReady() 方法,然后是啟動Watchdog。

接著則進入階段 600 ,實現該階段的回調方法的服務較多。

Phase 1000

WallpaperManagerService、InputMethodManagerService、LocationManagerService、CountryDetectorService、NetworkTimeUpdateService、CommonTimeManagementService、TextServicesManagerService、AssetAtlasService、InputManagerService、TelephonyRegistry、MediaRouterService、MmsServiceBroker這些服務依次執行其 systemRunning() 方法。經過一定流程,當ActivityManagerServer進入 finishBooting() 時,則啟動流程進入階段 PHASE_BOOT_COMPLETED=1000 。

到此所有服務啟動完成,system_server進程啟動完成,則進入 Looper.loop() 狀態,隨時待命,等待MessageQueue中的消息到來,則馬上進入執行狀態。

四、服務分類

system_server進程,從源碼角度劃分為引導服務、核心服務、其他服務3類。

  1. 引導服務:ActivityManagerService、PowerManagerService、LightsService、DisplayManagerService、PackageManagerService、UserManagerService、SensorService共7項服務;
  2. 核心服務:BatteryService、UsageStatsService、WebViewUpdateService共3項服務;
  3. 其他服務:AlarmManagerService、VibratorService等共70多項服務

合計總大約80多個服務,下面只是簡單地對所有服務分類(個人劃分,便于后期分析):

  1. 重量級服務: ActivityManagerServicePackageManagerServiceWindowManagerService
  2. 功耗相關: PowerManagerService 、BatteryService、BatteryStatsService、DreamManagerService
  3. 統計調度相關: DropBoxManagerServiceSamplingProfilerService 、UsageStatsService、DiskStatsService、SchedulingPolicyService、DeviceStorageMonitorService、AlarmManagerService、DeviceIdleController、DockObserver、ThermalObserver、JobSchedulerService、AccessibilityManagerService
  4. UI相關: DisplayManagerService、LightsService、GraphicsStatsService、StatusBarManagerService、NotificationManagerService、WallpaperManagerService、UiModeManagerService、AppWidgetService、LauncherAppsService、TextServicesManagerService、ContentService、LockSettingsService、InputManagerService、InputMethodManagerServiceMountService、FingerprintService、TvInputManagerService
  5. 網絡相關: NetworkManagementService、NetworkScoreService、NetworkStatsService、NetworkPolicyManagerService、ConnectivityService、BluetoothService、WifiP2pService、WifiService、WifiScanningService、EthernetService、WebViewUpdateService
  6. Media相關: AudioService、MediaRouterService、VoiceInteractionManagerService、MediaProjectionManagerService、MediaSessionService、
  7. 設備相關: DevicePolicyManagerService、PrintManagerService、BackupManagerService、UserManagerService、AccountManagerService、TrustManagerService、 SensorService 、LocationManagerService、VibratorService、CountryDetectorService、GestureLauncherService、PersistentDataBlockService、ClipboardService
  8. 其他: TelephonyRegistry、TelecomLoaderService、NsdService、UpdateLockService、SerialService、SearchManagerService、CommonTimeManagementService、AssetAtlasService、ConsumerIrService、MidiServiceCameraService、TwilightService、RestrictionsManagerService、MmsServiceBroker、RttService、UsbService。

后續,會針對其中比較重要的服務進行展開詳解。

來自: http://gityuan.com/2016/02/20/android-system-server-2/

 本文由用戶 co518248 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!