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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,717评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,501评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,311评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,417评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,500评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,538评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,557评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,310评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,759评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,065评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,233评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,909评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,548评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,172评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,420评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,103评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,098评论 2 352