Android 系統服務 - AMS 的啓動過程

相關文章鏈接:

1. Android Framework - 學習啓動篇
2. Android Framework - 開機啓動 SystemServer 進程

相關源碼文件:

/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/am/ActivityManagerService.java

ActivityManagerService 是 Android 中非常重要的一個服務,主要功能是管理和啓動四大組件。其源代碼大約有 2W 多行,這裏我們主要來分析其啓動過程,後面的文章我們肯定還會分析具體的源碼細節。AMS 是由 SystemServer 進程啓動的,對於這個有不瞭解的同學請看這裏《Android Framework - 開機啓動 SystemServer 進程》

    private void startBootstrapServices() {
      ...
      // 啓動 AMS 服務 
      mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();

      // 設置 AMS 的系統服務管理器
      mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
      // 設置 AMS 的 APP 安裝器
      mActivityManagerService.setInstaller(installer);
      ...

      // 設置 SystemServer 
      mActivityManagerService.setSystemProcess();
    }

    public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;

        public Lifecycle(Context context) {
            super(context);
            // 創建 ActivityManagerService
            mService = new ActivityManagerService(context);
        }

        @Override
        public void onStart() {
            // 調用 start 方法
            mService.start();
        }

        // 獲取 ActivityManagerService
        public ActivityManagerService getService() {
            return mService;
        }
    }

    // Note: This method is invoked on the main thread but may need to attach various
    // handlers to other threads.  So take care to be explicit about the looper.
    public ActivityManagerService(Context systemContext) {
        mContext = systemContext;
        // 獲取 ActivityThread
        mSystemThread = ActivityThread.currentActivityThread();

        // 創建名爲"ActivityManager"的前臺 HandlerThread
        mHandlerThread = new ServiceThread(TAG,
                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
        // 啓動 ServiceThread
        mHandlerThread.start();
        // 創建一個 MainHandler 與 mHandlerThread 公用一個 looper 
        mHandler = new MainHandler(mHandlerThread.getLooper());
        // 創建 UiHandler 其內部也會創建一個 HandlerThread
        mUiHandler = new UiHandler();
        // 前臺和後臺廣播接收隊列,分別是 10s 和 60s 放棄執行
        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
                "foreground", BROADCAST_FG_TIMEOUT, false);
        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
                "background", BROADCAST_BG_TIMEOUT, true);
        mBroadcastQueues[0] = mFgBroadcastQueue;
        mBroadcastQueues[1] = mBgBroadcastQueue;

        // 創建目錄/data/system
        File dataDir = Environment.getDataDirectory();
        File systemDir = new File(dataDir, "system");
        systemDir.mkdirs();
        // 創建 BatteryStatsService,相當於電錶
        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
        mBatteryStatsService.getActiveStatistics().readLocked();
        mBatteryStatsService.scheduleWriteToDisk();
        mBatteryStatsService.getActiveStatistics().setCallback(this);
        // 創建進程統計服務,信息保存在目錄 /data/system/procstats,
        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
        ...
        // 創建 ActivityStackSupervisor 對象
        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
        // 創建名爲 "CpuTracker" 的線程
        mProcessCpuThread = new Thread("CpuTracker") {
            @Override
            public void run() {
                while (true) {
                    try {
                        ...
                        updateCpuStatsNow();
                    } catch (Exception e) {
                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
                    }
                }
            }
        };
        // 看門狗
        Watchdog.getInstance().addMonitor(this);
        Watchdog.getInstance().addThread(mHandler);
    }

在 SystemService 進程的啓動過程中會調用 startBootstrapServices 方法,其內部會啓動 AMS 服務,在 ActivityManagerService 的構造函數中會創建三個線程分別是 ActivityManager 、UI 和 CpuTracker。我們接着看 start 方法:

    private void start() {
        // 移除所有的進程組
        Process.removeAllProcessGroups();
        // 啓動 CpuTracker 線程
        mProcessCpuThread.start();
        // 把電錶服務註冊添加到 ServiceManager
        mBatteryStatsService.publish(mContext);
        mAppOpsService.publish(mContext);
        Slog.d("AppOps", "AppOpsService published");
        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
    }

    public void setSystemProcess() {
        try {
            // 把自己加到 ServiceManager ,然後註冊額外的一些服務
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
            ServiceManager.addService("meminfo", new MemBinder(this));
            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
            ServiceManager.addService("dbinfo", new DbBinder(this));
            if (MONITOR_CPU_USAGE) {
                ServiceManager.addService("cpuinfo", new CpuBinder(this));
            }
            ServiceManager.addService("permission", new PermissionController(this));
            ServiceManager.addService("processinfo", new ProcessInfoService(this));
            // 通過 pms 獲取 ApplicationInfo 信息
            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                    "android", STOCK_PM_FLAGS);
            // 初始化 ApplicationInfo 和 ClassLoader
            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());

            synchronized (this) {
                // 創建 ProcessRecord 對象
                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
                app.persistent = true;
                app.pid = MY_PID;
                app.maxAdj = ProcessList.SYSTEM_ADJ;
                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
                synchronized (mPidsSelfLocked) {
                    mPidsSelfLocked.put(app.pid, app);
                }
                updateLruProcessLocked(app, false, null);
                updateOomAdjLocked();
            }
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(
                    "Unable to find android system package", e);
        }
    } 

    private void startOtherServices() {
      ...
      // 安裝系統 Provider 
      mActivityManagerService.installSystemProviders();
      ...

      mActivityManagerService.systemReady(new Runnable() {
       public void run() {
             // 啓動 WebView
             WebViewFactory.prepareWebViewInSystemServer();
             // 啓動 SystemUi
             startSystemUi(context);
             // 調用一系列服務的 systemReady 方法
             ...
             // 調用一系列服務的 systemRunning 方法
             ...
        }
      }
    }

    public void systemReady(final Runnable goingCallback) {
        ...
        // 執行 Callback 的 run 方法
        if (goingCallback != null) goingCallback.run();
        // Start up initial activity.
        mBooting = true;
        // 啓動桌面 Activity 進程
        startHomeActivityLocked(mCurrentUserId, "systemReady");
    }

    static final void startSystemUi(Context context) {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.android.systemui",
                    "com.android.systemui.SystemUIService"));
        //Slog.d(TAG, "Starting service: " + intent);
        context.startServiceAsUser(intent, UserHandle.OWNER);
    }

關於 AMS 的啓動流程還是很簡單的,調用構造函數會初始化三個線程;調用 setSystemProcess 方法中會向 ServcieManager 進程額外發布一些服務:procstats(進程信息)、meminfo(內存信息)、gfxinfo(圖形信息)、cpuinfo(cpu信息)、permission(權限)、processinfo(應用使用情況)等;調用 systemReady 方法首先會啓動 SystemUIService,然後執行一系列服務的 systemReady 和 systemRunning 方法,最後啓動桌面 Activity 進程。

視頻地址:https://pan.baidu.com/s/1dM3K9bPRuepFUJIASIDeQg
視頻密碼:af97

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章