面试题

AMS启动过程

2019-10-18  本文已影响0人  simplehych

com.android.server.am.ActivityManagerService

本文在 API 27 基础上展开分析。
文章篇幅的长度与附上的代码量有关,请耐心查看。
没时间的小伙伴,可以先大概浏览,有一个感性认识,后续再进行研究。

本文也是参考学习,如有错误,欢迎指正~

本文分析AMS启动过程的主要流程,并非全部。
有针对性和选择性的分析AMS的相关代码,非AMS的暂不讨论。

为防止深入代码导致记忆混乱,采用 step 标识跟进,例如 step 1step 1.1step 1.1.1 标识从某个方法入口依次跟进。

摘要

AMS - ActivityManagerService ,是 Android 最核心 的服务,主要负责系统中 四大组件 的启动、切换、调度及应用程序的管理和调度等工作。

AMS通信结构如下图所示:

AMS通信

关键词

  1. AMS:ActivityManagerService ;PMS-PackageManagerService;
  2. 系统服务;普通应用;Client / Service 思想;
  3. Application;ApplicationInfo;
  4. SystemServiceManager;ServiceManager;LocalServices;

AMS启动过程

为使读者对AMS启动有明确的方向,先将大致流程抛出来,方便整体把控。

  1. 创建出 SystemServer 进程的 Android 运行环境
  2. AMS 的初始化和启动
  3. SystemServer 进程纳入到 AMS 的管理体系
  4. AMS 启动完成的后续工作

前提 已知

  1. Zygote 创建 fork 出的第一个 java 进程是 SystemServer
  2. 每个进程的入口是 main 函数。
com.android.internal.os.Zygote

public static void main(String argv[]) {
    ...
    Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
    ...
}

整个过程从 SystemServer 进程的入口开始分析,涉及 AMS 启动主要过程的伪代码如下:

com.android.server.SystemServer

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

private void run() {
    try {
        ...
        // Initialize native services.
        System.loadLibrary("android_servers");
        ...
        // Initialize the system context.
        // systemServer在启动任何服务之前,先调用了createSystemContext 创建出 mSystemContext
        // step 1 
        createSystemContext();

        // Create the system service manager.
        // SystemServiceManager 负责启动所有的 系统服务
        // mSystemContext 构造出 SystemServiceManager,
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        ...
        // LocalServices 管理当前进程的服务
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        ...
    } finally {
        ....
    }

    // Start services.
    try {
        ...
        // step 2 启动引导服务,在其中创建并启动AMS
        startBootstrapServices();
        ...
        // step 3 启动其他服务,在其中AMS注册了SettingsProvider和其他后续工作
        startOtherServices();
        ...
    } catch (Throwable ex) {
        ...
    } finally {
        ...
    }
    ...
    // Loop forever.
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

Step 1 createSystemContext()

创建出 SystemServer 进程的 Android 运行环境

com.android.server.SystemServer

private void createSystemContext() {
    // step 1.1 调用ActivityThread的systemMain函数,其中会创建出系统对应的Context对象
    ActivityThread activityThread = ActivityThread.systemMain();
    // step 1.2 取出上面函数创建的Context对象,保存在mSystemContext中
    mSystemContext = activityThread.getSystemContext();
    // 设置系统主题
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
    ...
}

Step 1.1 ActivityThread.systemMain()

调用 ActivityThreadsystemMain() 函数,其中会创建出系统对应的 Context 对象

android.app.ActivityThread

public static ActivityThread systemMain() {
    //虽然写着ActivityManager,但和AMS没有任何关系,就是利用系统属性和配置信息进行判断
    if (!ActivityManager.isHighEndGfx()) {
        //低版本关闭硬件渲染功能
        ThreadedRenderer.disable(true);
    } else {
        ThreadedRenderer.enableForegroundTrimming();
    }

    // step 1.1.1 创建ActivityThread
    ActivityThread thread = new ActivityThread();
    //step 1.1.2 调用attach函数,参数为true
    thread.attach(true);
    return thread;
}

ActivityThread 有自己的 main 入口函数,明确此处调用的是 systemMain()

ActivityThread#systemMain() 了解到主要功能有:

  1. 判断是否开启硬件加速。
  2. 创建 ActivityThread 对象。
  3. 调用 thread 对象的 attach(true),注意参数 system 传入** true**。
Step 1.1.1 ActivityThread thread = new ActivityThread();

ActivityThread 的构造函数比较简单

com.android.app.ActivityThread

ActivityThread() {
    mResourcesManager = ResourcesManager.getInstance();
}

比较关键的是它内部的成员变量

com.android.app.ActivityThread

public final class ActivityThread {
    ...
    //定义了AMS与应用通信的接口
    final ApplicationThread mAppThread = new ApplicationThread();

    //拥有自己的looper,说明ActivityThread确实可以代表事件处理线程
    final Looper mLooper = Looper.myLooper();

    //H继承Handler,ActivityThread中大量事件处理依赖此Handler
    final H mH = new H();

    //用于保存该进程的ActivityRecord
    final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>()
    ...
    //用于保存进程中的Service
    final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
    ...
    //用于保存进程中的Application
    final ArrayList<Application> mAllApplications = new ArrayList<Application>();
    ...
}

ActivityThread,是 Android Framework 中一个非常重要的类,它代表应用进程主线程,其职责是调度及执行在该线程中运行的四大组件。

在Android中
应用进程,指那些运行Apk的进程,它们有Zygote fork出来,其中运行着独立的dalvik虚拟机。
系统进程,也应用进程相对,例如 Zygote 和 SystemServer。其中SystemServer 也是由Zygote fork出来的,也运行着一些系统Apk,例如 framework-res.apkSettingsProvider.apk 等,该进程也创建了主线程ActivityThread,所以SystemServer也可以看做是特殊的应用进程

对于上面提到的ActivityThread的成员变量,其用途基本上可以从名称中得知,这里仅说明一下ApplicationThread。

AMS负责 进管理进程调度,因此 AMS 和应用进程之间通信需要 Binder机制。为此 Android 提供了一个 android.app.IApplicationThread 接口,继承 IInterface,该接口定义了 AMS 和应用进程之间的交互函数。例如:scheduleLaunchActivityscheduleCreateService

当 AMS 与应用进程通信时,ApplicationThread 继承 IApplicationThread.Stub 作为Binder通信的服务端。

step 1.1.2 thread.attach(true);
android.app.ActivityThread

//此时,我们传入的参数为true,表示该ActivityThread是**系统进程的ActivityThread**
private void attach(boolean system) {
    //创建出的ActivityThread保存在类的静态变量sCurrentActivityThread
    //AMS中的大量操作将会依赖于这个ActivityThread
    sCurrentActivityThread = this;
    mSystemThread = system;

    if (!system) {
        //  '应用进程' 的处理流程
       ...
    } else { 
        // '系统进程' 的处理流程,该情况只在SystemServer中处理

        // Don't set application object here -- if the system crashes,
        // we can't display an alert, we just want to die die die.
        //设置DDMS(Dalvik Debug Monitor Service)中看到的SystemServer进程的名称为“system_process”
        android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId());

        try {
            // 创建ActivityThread中的重要成员:
            // Instrumentation、Application、Context
            // step 1.1.2.1 
            mInstrumentation = new Instrumentation();
            // step 1.1.2.3
            ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo); // step 1.1.2.2
             // step 1.1.2.4
            mInitialApplication = context.mPackageInfo.makeApplication(true, null);
            mInitialApplication.onCreate();
        } catch (Exception e) {
            ...
        }
    }

    //以下系统进程和非系统进程均会执行
    ...
    //注册Configuration变化的回调通知
    ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            //当系统配置发生变化时(例如系统语言发生变化),回调该接口
            ...
        }
       ...
    });
}

系统进程在ActivityThread的attach函数的主要工作:

  1. 创建Instrumentation
  2. 创建Context
    Context是Android中的一个抽象类,用于维护应用运行环境的全局信息。
    通过Context可以访问应用的资源和类,甚至进行系统级的操作,例如启动Activity、发送广播等。
  3. 创建Application
step 1.1.2.1 new Instrumentation()

Instrumentation是Android中的一个工具类,当该类被启动时,它将优先于其它的类被初始化。
此时,系统先创建它,再通过它创建其它组件。

此外,系统和应用组件之间的交互也将通过Instrumentation来传递。
因此,Instrumentation就能监控系统和组件的交互情况了。

实际使用时,可以创建该类的派生类进行相应的操作。
这个类在介绍启动Activity的过程时还会碰到,此处不作展开。

step 1.1.2.2 getSystemContext()
android.app.ActivityThread

public ContextImpl getSystemContext() {
    synchronized (this) {
        if (mSystemContext == null) {
            //调用ContextImpl的静态函数createSystemContext
            // step 1.1.2.2.1
            mSystemContext = ContextImpl.createSystemContext(this);
        }
        return mSystemContext;
    }
}

step 1.1.2.2.1 ContextImpl.createSystemContext

android.app.ContextImpl

static ContextImpl createSystemContext(ActivityThread mainThread) {
    // 创建LoadedApk类,代表一个加载到系统中的APK
    // 注意现在处于构建Android运行环境阶段,PMS服务还没有启动,无法得到有效的Application,后续PMS启动后,后调用 LoadedApk.installSystemApplicationInfo 进行填充
    // 此时实例化的LoadedApk只是一个空壳,内部使用空的Application
    // step 1.1.2.2.1.1 
    LoadedApk packageInfo = new LoadedApk(mainThread);

    //调用ContextImpl的构造函数,参数中传入了上面生成的对象packageInfo
    ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
            null);
    // 初始化资源 
    context.setResources(packageInfo.getResources());
    context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
            context.mResourcesManager.getDisplayMetrics());
    return context;
}

createSystemContext的主要工作:

  1. 创建一个 LoadApk,代表一个加载到系统中的Apk
  2. 将传入的线程参数 mainThread 和 上一步生成的packageInfo 实例化一个ContextImpl对象

似乎没有什么特别的,那么为什么函数名叫做 createSystemContext ??
为了回答这个问题,就要看看LoadedApk的构造函数

step 1.1.2.2.1.1

android.app.LoadApk

LoadedApk(ActivityThread activityThread) {
    mActivityThread = activityThread;
    mApplicationInfo = new ApplicationInfo();

    //packageName为"android"
    mApplicationInfo.packageName = "android";
    mPackageName = "android";
    //下面许多参数为null
    ...
}

注意到 mPackageName = "android",也就是 framework-res.apk。该Apk仅供SystemServer进程使用,因此上一步的方法名被定义成 createSystemContext

又注意到,实例化了一个mApplicationInfo对象,但是只赋值了其中的packageName属性,所以说现在的LoadedApk只是一个空壳。ApplicationInfo中包含了许多Apk重要信息,当之后的PMS启动,完成对应的解析后,AMS将重新调用 LoadedApk.installSystemApplicationInfo 进行填充。

step 1.1.2.3 ContextImpl.createAppContext
android.app.ContextImpl

static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
    if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
    ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
            null);
    context.setResources(packageInfo.getResources());
    return context;
}

createAppContext的工作比较简单,利用 ActivityThread 和 LoadApk 构造出 ContextImpl。

ContextImpl的构造函数主要是完成了一些变量的初始化,建立起 ContextImpl 与 ActivityThread、LoadApk、ContentResolver 之间的关系。
以后可以从 ContextImpl中 获取一些变量。

注意 createAppContext 和 上一步的 createSystemContext 中构造 ContextImpl是一样的

代码简单,不再展开,注意在函数的最后建立和 ContentResolver 之间的联系

mContentResolver = new ApplicationContentResolver(this, mainThread, user);
step 1.1.2.4 context.mPackageInfo.makeApplication

先来看一下 Application 关系图

Application 关系图

Android中Application类用于保存应用的全局状态

Activity和Service都和具体的Application绑定在一起,通过继承关系可知,每个Activity和Service均加入到Android运行环境中。

android.app.ActivityThread

private void attach(boolean system) {
    ...
        // mPackageInfo是LoadApk类型,从context中获取LoadApk,然后调用LoadApk的makeApplication函数
        // step 1.1.2.4
    mInitialApplication = context.mPackageInfo.makeApplication(true, null);
    // 调用Application的onCreate方法
    mInitialApplication.onCreate();
    ...
}
android.app.LoadedApk

public Application makeApplication(boolean forceDefaultAppClass,
        Instrumentation instrumentation) {
    ...

    Application app = null;

    String appClass = mApplicationInfo.className;
    // 此流程 forceDefaultAppClass == true
    if (forceDefaultAppClass || (appClass == null)) {
        // 系统进程中,对应下面的appClass
        appClass = "android.app.Application";
    }

    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) {
        ...
    }
    //一个进程支持多个Application,mAllApplications用于保存该进程中的Application对象
    mActivityThread.mAllApplications.add(app);
    mApplication = app;

    // 此流程 instrumentation == null
    if (instrumentation != null) {
        try {
            instrumentation.callApplicationOnCreate(app);
        } catch (Exception e) {
            ...
        }
    }

    // Rewrite the R 'constants' for all library apks.
    ...
    return app;
}

makeApplication 的主要工作:

  1. 创建 framework-res.apk 对应的Application
  2. 调用Application的onCreate函数

总结 createSystemContext

至此,createSystemContext函数介绍完毕。

当 SystemServer 调用 createSystemContext 完毕后:

  1. 得到一个 ActivityThread 对象,它代表当前进程(系统进程)的主线程
  2. 得到一个 Context,对于 SystemServer 而言,它包含 Application 运行环境 和 framework-res.apk(名为"android"的LoadedAPK) 有关。

思考

Q:为什么启动所有的服务前,SystemServer先要调用createSystemContext?
A:众所周知,Android是以Java为基础的,Java运行在进程中。
但是,Android想努力构筑一个自己的运行环境,组件的运行和它们之间的交互均在该环境中实现。

createSystemContext 函数就是为* SystemServer系统进程* 搭建一个和 普通应用进程 一样的 Android环境

Android运行环境,是在进程的基础上构建的,但是把 进程的概念被模糊化,所以应用程序一般只和Android运行环境交互。

基于同样的道理,Android 希望 SystemServer进程内部运行的应用,也通过Android运行环境交互,因此才调用了 createSystemContext 函数。

创建Android运行环境时,
由于SystemServer的特殊性,SystemServer.main() 调用了 ActivityThread.systemMain() 函数
对于普通的应用程序,将在自己的主线程汇中调用 ActivityThread.main() 函数

进程 的 Android运行环境 涉及的主要类之间的关系如下图,其中核心类是ContextImpl ,通过它可以得到 ContentResolver、系统资源Resources、应用信息Application、当前进程的主线程ActivityThread、Apk信息LoadedApk等。

Android 运行环境涉及的主要类之前的关系

Step 2 AMS初始化

Step 1 创建完Android运行环境和创建系统服务管理后,创建了SystemServiceManager,并将其加入到了 LocalServices 中。

com.android.server.SystemServer

private void run() {
    // Step 1
    createSystemContext();
    // Create the system service manager.
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
    ...
    // Step 2
    startBootstrapServices();
}

之后,SystemServer 就调用了 startBootstrapServices
正式进入AMS的创建和启动过程

伪代码如下:

com.android.server.SystemServer

private void startBootstrapServices() {
    Installer installer = mSystemServiceManager.startService(Installer.class);
    ...
   
    // Activity manager runs the show.
    // 启动AMS,然后获取AMS保存到变量中
    // Step 2.1
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();

    //以下均是将变量存储到AMS中
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer); 
    ...
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    mPackageManager = mSystemContext.getPackageManager();
    ...
    // Set up the Application instance for the system process and get started.
    // Step 2.2
   mActivityManagerService.setSystemProcess();
   ...
   mPackageManagerService.systemReady();
   ...
   mActivityManagerService.systemReady(()->{ ... });
   ...

}

注意上面代码 mSystemServiceManager 并没有直接启动 AMS ,而是启动 AMS 的内部类ActivityManagerService.Lifecycle.
由于 AMS 并没有继承 SystemService ,因此不能通过 SystemServiceManager.startService() 直接启动(内部实现采用反射的方式),例如可以直接启动Installer

AMS 的内部类 Lifecycle 继承 SystemService ,像一个适配器来间接操作 AMS。让 AMS 能够 SystemService 一样被 SystemServiceManager 通过反射的方式启动。

Lifecycle类简单如下:

com.android.server.am.ActivityManagerService

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

   public Lifecycle(Context context) {
        super(context);
        // step 2.1.1 调用AMS的构造函数
        mService = new ActivityManagerService(context);
   }

   @Override
   public void onStart() {
        // step 2.1.2 调用AMS的start函数
        mService.start();
   }

   @Override
   public void onCleanupUser(int userId) {
        mService.mBatteryStatsService.onCleanupUser(userId);
   }

   public ActivityManagerService getService() {
        return mService;
   }
}
Step 2.1.1 AMS 构造函数

构造函数较长但简单,主要初始化了一些变量,可以过一遍

public ActivityManagerService(Context systemContext) {
    //AMS的运行上下文与SystemServer一致
    mContext = systemContext;
    ............
    //取出的是ActivityThread的静态变量sCurrentActivityThread
    //这意味着mSystemThread与SystemServer中的ActivityThread一致
    mSystemThread = ActivityThread.currentActivityThread();
    ............
    mHandlerThread = new ServiceThread(TAG,
            android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
    mHandlerThread.start();
    //处理AMS中消息的主力
    mHandler = new MainHandler(mHandlerThread.getLooper());

    //UiHandler对应于Android中的UiThread
    mUiHandler = new UiHandler();

    if (sKillHandler == null) {
        sKillThread = new ServiceThread(TAG + ":kill",
                android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
        sKillThread.start();
        //用于接收消息,杀死进程
        sKillHandler = new KillHandler(sKillThread.getLooper());
    }

    //创建两个BroadcastQueue,前台的超时时间为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;

    //创建变量,用于存储信息
    mServices = new ActiveServices(this);
    mProviderMap = new ProviderMap(this);
    mAppErrors = new AppErrors(mContext, this);

    //这一部分,分析BatteryStatsService时提过,进行BSS的初始化
    File dataDir = Environment.getDataDirectory();
    File systemDir = new File(dataDir, "system");
    systemDir.mkdirs();
    mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
    mBatteryStatsService.getActiveStatistics().readLocked();
    mBatteryStatsService.scheduleWriteToDisk();
    mOnBattery = DEBUG_POWER ? true
            : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
    mBatteryStatsService.getActiveStatistics().setCallback(this);

    //创建ProcessStatsService,感觉用于记录进程运行时的统计信息,例如内存使用情况,写入/proc/stat文件
    mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));

    //启动Android的权限检查服务,并注册对应的回调接口
    mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
    mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
            new IAppOpsCallback.Stub() {
                @Override public void opChanged(int op, int uid, String packageName) {
                    if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
                        if (mAppOpsService.checkOperation(op, uid, packageName)
                                != AppOpsManager.MODE_ALLOWED) {
                            runInBackgroundDisabled(uid);
                        }
                    }
                }
            });

    //用于定义ContentProvider访问指定Uri对应数据的权限,aosp中似乎没有这文件
    mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));

    //创建多用户管理器
    mUserController = new UserController(this);

    //获取OpenGL版本
    GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
    ............
    //资源配置信息置为默认值
    mConfiguration.setToDefaults();
    mConfiguration.setLocales(LocaleList.getDefault());
    mConfigurationSeq = mConfiguration.seq = 1;

    //感觉用于记录进程的CPU使用情况
    mProcessCpuTracker.init();

    //解析/data/system/packages-compat.xml文件,该文件用于存储那些需要考虑屏幕尺寸的APK的一些信息
    //当APK所运行的设备不满足要求时,AMS会根据xml设置的参数以采用屏幕兼容的方式运行该APK
    mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);

    //用于根据规则过滤一些Intent
    mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);

    //以下的类,似乎用于管理和监控AMS维护的Activity Task信息
    //ActivityStackSupervisor是AMS中用来管理Activity启动和调度的核心类
    mStackSupervisor = new ActivityStackSupervisor(this);
    mActivityStarter = new ActivityStarter(this, mStackSupervisor);
    mRecentTasks = new RecentTasks(this, mStackSupervisor);

    //创建线程用于统计进程的CPU使用情况
    mProcessCpuThread = new Thread("CpuTracker") {
        @Override
        public void run() {
            while (true) {
                try {
                    try {
                        //计算更新信息的等待间隔
                        //同时利用wait等待计算出的间隔时间
                        ......
                    } catch(InterruptedException e) {
                    }
                    //更新CPU运行统计信息
                    updateCpuStatsNow();
                } catch (Exception e) {
                    ..........
                }
            }
        }
    };

    //加入Watchdog的监控
    Watchdog.getInstance().addMonitor(this);
    Watchdog.getInstance().addThread(mHandler);
}
Step 2.1.2 AMS 的 start 函数
private void start() {
    //完成统计前的复位工作
    Process.removeAllProcessGroups();

    //开始监控进程的CPU使用情况
    mProcessCpuThread.start();

    //注册电池状态服务
    mBatteryStatsService.publish(mContext);

    //注册一些应用信息和控制的服务,比如权限等
    mAppOpsService.publish(mContext);
    
    // ActivityManagerInternal 是 activity manager 本地管理服务的接口
    LocalServices.addService(ActivityManagerInternal.class, new LocalService());
}

start() 函数的主要工作:

  1. 启动CPU监控线程,该线程将会开始统计不同进程使用CPU的情况
  2. 发布一些服务,如BatteryStatsService、AppOpsService(权限管理相关)和本地实现的LocalService继承ActivityManagerInternal的服务

至此,AMS 初始化完成
下一步将 SystemServer 纳入AMS的管理体系

step 2.2 AMS#setSystemProcess

public void setSystemProcess() {
   try {
        // step 2.2.1 以下几个向ServiceManager注册几个服务
        // AMS自己,在这里注册,以后通过ServiceManager获取,最常见的获取key为"activity"的服务
       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));
       //MONITOR_CPU_USAGE默认为true
      if (MONITOR_CPU_USAGE) {
           //用于输出进程的CPU使用情况
           ServiceManager.addService("cpuinfo", new CpuBinder(this));
       }
       //注册权限管理服务
       ServiceManager.addService("permission", new PermissionController(this));
        //注册获取进程信息的服务
       ServiceManager.addService("processinfo", new ProcessInfoService(this));

        // step 2.2.2 通过 PMS 查询 package 名为 "android" 的应用的ApplicationInfo,即系统应用
       ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
               "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
               
        // step 2.2.3 通过查询的结果进行安装
       mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());

        // step 2.2.4 以下与AMS的进程管理
       synchronized (this) {
           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);
   }
}

AMS的setSystemProcess有四个主要功能:

  1. ServiceManager 注册服务统一管理,如 AMS 本身。
  2. 获取 package 名为 "android" 的应用的 ApplicationInfo,即系统应用 framework-res.apk
  3. 调用 ActivityThreadinstallSystemApplicationInfo,回忆之前创建的 LoadedApk 是一个空壳,没有实际的 ApplicationInfo
  4. AMS 进程管理相关的操作
step 2.2.1 注册服务 ServiceManager.addService()
com.android.server.am.ActivityManagerService # setSystemProcess()

ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);

注意平时常用的 AMS 获取,要知道是在这里进行 添加 的。

Step 2.2.2 获取系统应用信息 getApplicationInfo
com.android.server.am.ActivityManagerService 

public void setSystemProcess() {
    ApplicationInfo info = mContext.getPackageManager() // Step 2.2.2.1
               .getApplicationInfo( "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY); // Step 2.2.2.2
}
Step 2.2.2.1 mContext.getPackageManager()

Context 的实现类是 ContextImpl

android.app.ContextImpl

public PackageManager getPackageManager() {
   if (mPackageManager != null) {
       return mPackageManager;
   }
    // 依赖于ActivityThread,此时为系统进程的主线程,调用ActivityThread的getPackageManager()函数
   IPackageManager pm = ActivityThread.getPackageManager();
   if (pm != null) {
       // Doesn't matter if we make more than one instance.
       // 利用PMS的代理对象,构建ApplicationPackageManager对象(继承PackageManager)
       // Note:PackageManager不继承IPackageManager。IPackageManager继承IInterface,属于Binder接口
       return (mPackageManager = new ApplicationPackageManager(this, pm));
   }
   return null;
}

跟进一下ActivityThread的getPackageManager:

android.app.ActivityThread

public static IPackageManager getPackageManager() {
   if (sPackageManager != null) {
       return sPackageManager;
   }
   // 依赖于Binder通信,并通过ServiceManager获取到PMS对应的BpBinder
   IBinder b = ServiceManager.getService("package");
   //得到PMS对应的Binder服务代理
   sPackageManager = IPackageManager.Stub.asInterface(b);
   return sPackageManager;
}

从上面我们可以看到,获取 PMS 用到了Binder通信。方式和获取 AMS 一样。

实际上,PMSSystemServer 创建,与 AMS 运行在同一一个进程,且初始化比 AMS 早,但是比构建 Android 运行环境晚,所以之前构建的系统 LoadedApk 是一个空壳,实际内容需要从 PMS 中获取。

实际上,AMS 完全可以不经过 ContextActivityThreadBinder 来获取 PMS,直接在 SystemServer 中取 mPackageManagerService 属性即可

但是源码通过 ActivityThread.getPackageManager 等之前和之后一系列操作获取 PMS 的原因是:
SystemServer 进程中的服务,也通过之前构建的 Android 运行环境来交互,保证了组件之间交互接口的统一,为未来的系统保留了可扩展性。

step 2.2.2.2 通过 PMS 获取 getApplicationInfo()

得到 PMS 服务的代理对象后,AMS 调用 PMSgetApplicationInfo 接口,获取 package 名为 "android" 的 ApplicationInfo

AMSsetSystemProcess 被调用前,PMS 已经启动了。
PMS 的构造函数中,它将解析手机中所有的AndroidManifest.xml,然后形成各种数据结构以维护应用的信息。

getApplicationInfo 就是通过 package 名,从对应的数据结构中取出对应的应用信息。这部分内容主要就是查询数据结构的内容,不作深入分析。

2.2.3 installSystemApplicationInfo

在上一步得到 framework-res.apkApplicationInfo 后,需要将该 ApplicationInfo 保存到 SystemServer 对应的ActivityThread 中。

com.android.server.am.ActivityMagerService

mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());

AMS 中的 mSystemThread 就是 SystemServer 中创建出的 ActivityThread

跟进一下 ActivityThreadinstallSystemApplicationInfo 函数

com.android.app.ActivityThread

public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
   synchronized (this) {
        //调用SystemServer中创建出的ContextImpl的installSystemApplicationInfo函数        
       getSystemContext().installSystemApplicationInfo(info, classLoader);
       getSystemUiContext().installSystemApplicationInfo(info, classLoader);

       // give ourselves a default profiler
       // 创建一个Profiler对象,用于性能统计
       mProfiler = new Profiler();
   }
}

继续跟进 ContextImplinstallSystemApplicationInfo 函数

com.android.app.ContextImpl

void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
    // mPackageInfo 的类型为 LoadedApk
   mPackageInfo.installSystemApplicationInfo(info, classLoader);
}

继续跟进 LoadedApkinstallSystemApplicationInfo 函数

com.android.app.LoadedApk

/**
* Sets application info about the system package.
*/
void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
    // 这个接口仅供系统进程调用,故这里断言了一下
   assert info.packageName.equals("android");
   mApplicationInfo = info;
   mClassLoader = classLoader;
}

至此,我们知道了 installSystemApplicationInfo 的真相就是:
将包名为 "android" 对应的 ApplicationInfo (framework-res.apk),加入到之前创建的系统 LoadedApk 中(SystemServer#run#createSystemContext)

原因是:在此之前创建 SystemContext 时,PMS 还没有执行对手机中的文件进行解析的操作,因此初始化的 LoadApk 并没有持有有效的 ApplicationInfo(仅实例化了一个空 ApplicationInfo 对象,设置了 packageName 属性为"android",其他并没有设置)。


在此基础上,AMS 下一步的工作就呼之欲出了

因为 AMS 是专门用于进程管理和调度的,但是framework.apk 运行在 SystemServer 进程中,所以SystemServer 进程也应该在 AMS 有对应的管理结构。(SystemServer 创建了 AMS,但是 AMS 还想管理SystemServer ^ - ^ )

于是,AMS 的下一步工作就是将 SystemServer 的运行环境和一个进程管理结构对应起来,并进行统一的管理。

2.2.4 AMS进程的管理

ProcessRecord 该类定义一个进程的详细信息
mLruProcess列表保存进程
进程对应的oom_adj值将决定进程是否被kill掉

AMS#setSystemProcess函数中,进程管理相关的代码如下:

com.android.server.am.ActivityManagerServer

public void setSystemProcess() {
    ...
    synchronized (this) {
        // 创建进程管理对应的结构 ProcessRecord
        ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
        
        // 由于此时创建的是SystemServer进程对应的ProcessRecord,因此设置了一些特殊值
        app.persistent = true;
        app.pid = MY_PID;
        app.maxAdj = ProcessList.SYSTEM_ADJ;
        // 将SystemServer对应的ApplicationThread保存到ProcessRecord中
        app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
        synchronized (mPidsSelfLocked) {
            // 按pid将ProcessRecord保存到mPidsSelfLocked中
            mPidsSelfLocked.put(app.pid, app);
        }
        // TODO 调整 mLruProcess 列表的位置,最近活动过的进程总是位于前列,同时拥有Activity的进程总是前于只有Service的进程
        updateLruProcessLocked(app, false, null);
        // TODO 更新进程对应的oom_adj值,oom_adj将决定进程是否被kill掉
        updateOomAdjLocked();
    }
    ...
}

这里我们仅分析一下创建进程管理结构的函数newProcessRecordLocked。
updateLruProcessLocked和updateOomAdjLocked函数比较复杂,等对AMS有更多的了解后,再做分析。

com.android.server.am.ActivityManagerServer

final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, boolean isolated, int isolatedUid) {
    //进程的名称
    String proc = customProcess != null ? customProcess : info.processName;

    //将用于创建该进程的电源统计项
    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();

    final int userId = UserHandle.getUserId(info.uid);
    //isolated此时为false
    if (isolated) {
        ...
    }
    //创建出对应的存储结构
    final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);

    //判断进程是否常驻
    if (!mBooted && !mBooting
            && userId == UserHandle.USER_SYSTEM
            && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
        r.persistent = true;
    }

    //按进程名将ProcessRecord存入到AMS的变量mProcessNames中
    //该变量的类型为ProcessMap<ProcessRecord> 
    //结合前面的代码,我们知道AMS有两种方式可以取到ProcessRecord,一是根据进程名,二是根据进程名称
    addProcessNameLocked(r);
    return r;
}

跟进一下 ProcessRecord 的构造函数

com.android.server.am.ProcessRecord

ProcessRecord(BatteryStatsImpl _batteryStats, ApplicationInfo _info,
        String _processName, int _uid) {
    mBatteryStats = _batteryStats; //用于电量统计
    info = _info;  //保存ApplicationInfo
    ...........
    processName = _processName;  //保存进程名

    //一个进程能运行多个Package,pkgList用于保存package名
    pkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.versionCode));

    //以下变量和进程调度优先级有关
    maxAdj = ProcessList.UNKNOWN_ADJ;
    curRawAdj = setRawAdj = ProcessList.INVALID_ADJ;
    curAdj = setAdj = verifiedAdj = ProcessList.INVALID_ADJ;

    //决定进程是否常驻内存(即使被杀掉,系统也会重启它)
    persistent = false;

    removed = false;
    lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis();
}

总结
AMS#setSystemProcess 函数主要完成任务:

  1. ServiceManager 添加注册了一些服务,包括 AMS 自身。
  2. 通过 PMS 获取 "android" 系统服务的 ApplicationInfo 信息,并安装到系统服务对应的 LoadedApk 中。
  3. 构建 SystemServer 进程对应的 ProcessRecord,将SystemServer 纳入到 AMS 的管理中。

Step 3 SystemServer#startOtherServices

接下来AMS启动相关的操作,在SystemServer的startOtherServices函数中

com.android.server.SystemServer

private void startOtherServices() {
    ...
    // Step 3.1
    mActivityManagerService.installSystemProviders();
    ...
    // Step 3.2
    mActivityManagerService.systemReady(new Runnable() {
        ...
    });
}

继续跟进AMS的installSystemProviders函数

Step 3.1 AMS # installSystemProviders

com.android.server.am.ActivityManagerServer

public final void installSystemProviders() {
    List<ProviderInfo> providers;
    synchronized (this) {
        // AMS 根据进程名取出对应的ProcessRecord
      ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
      // 得到该ProcessRecord对应的ProviderInfo
      // Step 3.1.1
      providers = generateApplicationProvidersLocked(app);
      // 仅处理系统级的Provider,取出非系统
      if (providers != null) {
          for (int i=providers.size()-1; i>=0; i--) {
              ProviderInfo pi = (ProviderInfo)providers.get(i);
              if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
                  Slog.w(TAG, "Not installing system proc provider " + pi.name
                          + ": not system .apk");
                  providers.remove(i);
              }
          }
      }
    }
    if (providers != null) {
      // 安装Provider
       // Step 3.1.2
      mSystemThread.installSystemProviders(providers);
    }
    
    mConstants.start(mContext.getContentResolver());
    // 监控Settings数据库中的secure、System和Global表的变化
    mCoreSettingsObserver = new CoreSettingsObserver(this);
    // 创建监控数据库中字体大小的变化
    mFontScaleSettingObserver = new FontScaleSettingObserver();
    
    // Now that the settings provider is published we can consider sending
    // in a rescue party.
    RescueParty.onSettingsProviderPublished(mContext);
    
    //mUsageStatsService.monitorPackages();
}

从上面的代码可以看出,AMS # installSystemProviders主要是加载运行在 SystemServer 进程中的 ContentProvider,即SettingProvider.apk(frameworks/base/packages/SettingsProvider)

framework-res.apk 源码的位置:frameworks/base/core/res
SettingProvider.apk 源码的位置:frameworks/base/packages/SettingsProvider

framework-res.apk 源码 SettingProvider.apk

上面有两个比较重要的函数:

  1. generateApplicationProvidersLocked 返回一个进程对应的 ProviderInfo 列表。
  2. ActivityThread 可以看做进程Android运行环境,因此它的 installSystemProviders 表示为对应进程安装ContentProvider
  3. SettingProvider 被加载到 SystemServer 进程中运行后,AMS 就注册了两个 ContentObserver 监控SettingsProvider 中的字段变化

AMS 监控的字段影响范围比较广,例如字体发生变化时,很多应用的显示界面需要作出调整,这也许就是让 AMS来 负责监控这些字段的原因

接下来,我们看上面比较重要的两个函数

Step 3.1.1
com.android.server.am.ActivityServiceManager

private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
   List<ProviderInfo> providers = null;
   try {
        // 利用 PMS 根据进程名及权限,从数据结构中得到进程对应的ProviderInfo
       providers = AppGlobals.getPackageManager()
               .queryContentProviders(app.processName, app.uid,
                       STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
                               | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
               .getList();
   } catch (RemoteException ex) {
   }
   if (DEBUG_MU) Slog.v(TAG_MU,
           "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
   int userId = app.userId;
   if (providers != null) {
   
        // 通常而言,我们逐渐向容器加入数据时,容器只有在数据超出当前存储空间时
        // 才会运行内存的重新分配(一般乘2)和数据的拷贝
        // 因此若待加入数据总量很大,在逐步向容器加入数据的过程,容器将会有多次重新分配和拷贝的过程
        // 或许整体的开销并不是很惊人,但事先将内存一次分配到位,体现了对极致的追求
        // 建议学习
       int N = providers.size();
       app.pubProviders.ensureCapacity(N + app.pubProviders.size());
       
       for (int i=0; i<N; i++) {
           // TODO: keep logic in sync with installEncryptionUnawareProviders
           ProviderInfo cpi =
               (ProviderInfo)providers.get(i);
               // 判断是否为单例的
           boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
                   cpi.name, cpi.flags);
                   // 针对多用户的处理
                   // 若一个Provider是单例的,但当前进程不属于默认用户,那么这个Provider将不被处理
                   // 简单来说,就是两个用户都启动一个进程时(有了两个进程)
                   // 定义于进程Package中单例的Provider仅运行在默认用户启动的进程中
           if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
               // This is a singleton provider, but a user besides the
               // default user is asking to initialize a process it runs
               // in...  well, no, it doesn't actually run in this process,
               // it runs in the process of the default user.  Get rid of it.
               providers.remove(i);
               N--;
               i--;
               continue;
           }

            // 包名和类名组成ComponentName
           ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
           // 创建ContentProvider对应的ContentProviderRecord
           // 加入到AMS的MProviderMap中
           ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
           if (cpr == null) {
               cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
               mProviderMap.putProviderByClass(comp, cpr);
           }
           // 将ContentProviderRecord保存在ProcessRecord中
           app.pubProviders.put(cpi.name, cpr);
           if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
               // Don't add this if it is a platform component that is marked
               // to run in multiple processes, because this is actually
               // part of the framework so doesn't make sense to track as a
               // separate apk in the process.
               // 当ContentProvider仅属于当前进程时,还需要统计该Provider的运行信息
               app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
                       mProcessStats);
           }
           //通知PMS记录该Provider对应包被使用的时间
           notifyPackageUse(cpi.applicationInfo.packageName,
                            PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
       }
   }
   return providers;
}

generateApplicationProvidersLocked 函数实现的主要功能:

  1. PMS 中得到应用对应的 ContentProvider
  2. 利用应用信息和对应的 ContentProvider 组成ContentProviderRecord
  3. ContentProviderRecord 按包名保存到 AMSmProviderMap 中。原因:AMS 需要管理。ContentProvider,当一个进程退出时,AMS 需要将其中运行的 ContentProvider 信息从系统中移除。
  4. ContentProviderRecord 按包名保存到 ProcessRecord 中。原因:最终需要落实到一个进程中。
Step 3.1.2 ActivityThread # installSystemProviders
com.android.app.ActivityThread

public final void installSystemProviders(List<ProviderInfo> providers) {
    if (providers != null) {
          //对于SystemServer进程而言,mInitialApplication是framework-res.apk对应的Application
      installContentProviders(mInitialApplication, providers);
    }
}

####### Step 3.1.2.1 ActivityThread # installContentProviders

com.android.app.ActivityThread

private void installContentProviders(
       Context context, List<ProviderInfo> providers) {
   final ArrayList<ContentProviderHolder> results = new ArrayList<>();

   for (ProviderInfo cpi : providers) {
       ...
       // Step 3.1.2.1.1 初始化并保存ContentProvider
       ContentProviderHolder cph = installProvider(context, null, cpi,
               false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
       if (cph != null) {
           cph.noReleaseNeeded = true;
           results.add(cph);
       }
   }

   try {
        // Step 3.1.2.1.2 向AMS注册ContentProvider
       ActivityManager.getService().publishContentProviders(
           getApplicationThread(), results);
   } catch (RemoteException ex) {
       throw ex.rethrowFromSystemServer();
   }
}

installContentProviders 是安装 ContentProvider 的通用程序,主要包括两方面的工作:

  1. 调用 installProvider 得到 ContentProviderHolder 对象,其间完成了对应 ContentProvider 的初始化等工作。
  2. AMS 发布 ContentProviderHolder

####### Step 3.1.2.1.1 ActivityThread # installProvider

com.android.app.ActivityThread
private ContentProviderHolder installProvider(Context context,
        ContentProviderHolder holder, ProviderInfo info,
        boolean noisy, boolean noReleaseNeeded, boolean stable) {
    ContentProvider localProvider = null;
    IContentProvider provider;
    if (holder == null || holder.provider == null) {
        // 此时holder==null,进入这个分支
        ...
        Context c = null;
        ApplicationInfo ai = info.applicationInfo;
        
        // 下面判断的作用是:为待安装的ContentProvider找到对应的Application
        // 在 AndroidManifest中,ContentProvider是Application的子标签,因此ContentPro与Application有一种对应关系
        // 本次流程中,传入的context是mInitApplication,代表的是framework-res.apk
        // 而 ai 是从ProviderInfo中获取的,代表的是SettingProvider,SettingProvider.apk所对应的Application还未创建
        // 所有进入最后的else判断中
        if (context.getPackageName().equals(ai.packageName)) {
            c = context;
        } else if (mInitialApplication != null &&
                mInitialApplication.getPackageName().equals(ai.packageName)) {
            c = mInitialApplication;
        } else {
            try {
                // 以下将重新创建一个Context,指向SettingProvider.apk
                // ai.packageName = "com.android.provider.settings"

                // createPackageContext方法中利用package对应的LoadedApk信息,创建新的ContextImpl
                // 其内部通过 mMainThread.getPackageInfo 取出LoadedApk,在这个过程中,如果已经加载过就直接从存储变量中取,否则同PMS重新构建
                c = context.createPackageContext(ai.packageName,
                        Context.CONTEXT_INCLUDE_CODE);
            } catch (PackageManager.NameNotFoundException e) {
                // Ignore
            }
        }
        
        ...

        try {
            // 上面必须找到ContentProvider对应的Context的原因:
            // 1. ContentProvider和Application有对应关系,而Application继承Context
            // 2. 只有正确的Context才能加载对应APK的Java字节码,从而通过反射创建出ContentProvider实例

            // 得到对应的ClassLoader
            final java.lang.ClassLoader cl = c.getClassLoader();
            // 反射创建实例
            localProvider = (ContentProvider)cl.
                loadClass(info.name).newInstance();

            // ContentProvider的mTransport对象
            // 变现类型为IContentProvider,实际为ContentProviderNative,即ContentProvider的Binder通信服务端BbBinder
            // Tansport 继承 ContentProviderNative
            provider = localProvider.getIContentProvider();

            ...

            // 初始化ContentProvider,内部会调用ContentProvider的onCreate函数
            localProvider.attachInfo(c, info);

        } catch (java.lang.Exception e) {
            ...
            return null;
        }
    } else {
        provider = holder.provider;
        ...
    }

    ContentProviderHolder retHolder;

    synchronized (mProviderMap) {
        ...
        // 调用ContentProviderNative的asBinder,得到服务端的Binder对象
        IBinder jBinder = provider.asBinder();
        if (localProvider != null) {
            ComponentName cname = new ComponentName(info.packageName, info.name);
            ProviderClientRecord pr = mLocalProvidersByName.get(cname);
            if (pr != null) {
                ...
                provider = pr.mProvider;
            } else {
                // 根据ProviderInfo创建ContenProviderHolder
                holder = new ContentProviderHolder(info);
                // 使持有provider
                holder.provider = provider;
                holder.noReleaseNeeded = true;

                // 构造ProviderClientRecord,并按authority将其保存在mProviderMap中
                pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
                // 将 pr 按 jBinder 保存在 mLocalProviders 中
                mLocalProviders.put(jBinder, pr);
                // 将 pr 按 cname 保存在 mLocalProvidersByName 中
                mLocalProvidersByName.put(cname, pr);
            }
            retHolder = pr.mHolder;
        } else {
            ...
        }
    }
    return retHolder;
}

installProvider 的代码较长,但实际思想很简单,就是环环相扣的三步:

  1. 创建出 ContentProvider 对应的 ContextImpl(代表对应的运行环境)
  2. 利用 ContextImpl 得到对应的 ClassLoader,完成 ContentProvider 的初始化和启动
  3. 得到与 ContentProvider 通信的 BBinder,然后按名称和 BBinder,将 ContentProvider 保存到对应的存储结构中“
ActivityThread 与 ContenProvider 的关系图

ActivityThread 与 ContenProvider 的关系大概如上图所示。

ContentProvider 本身只是一个容器,其内部持有的 Transport 类才是能提供跨进程调用的支持。

Transport 类继承自 ContentProviderNative 类,作为ContentProviderBinder 通信服务端 BBinder
ContentProviderNative 中定义的 ContentProviderProxy 类将作为 Binder 通信的服务端代理,为客户端提供交互

在上面的代码中,ActivityThreadmLocalProviders 保存运行在本地的 ContentProvider,使用的键值的key为 ContentProvider的Binder 通信服务端。

####### Step 3.1.2.1.1 publishContentProviders
ContentProvider 初始化完成后,我们需要向 AMS 注册它。

com.android.app.ActivityThread

private void installContentProviders(
    ...
    ActivityManager.getService().publishContentProviders(
                getApplicationThread(), results);
    ...
}

这段代码是注册ContentProvider的通用代码.

因此即使我们现在的流程运行在AMS中,此处仍然将通过Binder通信进行调用。

com.android.server.app.ActivityManagerService

public final void publishContentProviders(IApplicationThread caller,
        List<ContentProviderHolder> providers) {
    if (providers == null) {
        return;
    }

    enforceNotIsolatedCaller("publishContentProviders");
    synchronized (this) {
        //找到调用者对应的ProcessRecord对象
        final ProcessRecord r = getRecordForAppLocked(caller);
        ...

        final long origId = Binder.clearCallingIdentity();

        final int N = providers.size();
        for (int i = 0; i < N; i++) {
            // ProcessRecord的pubProviders中保存了ContentProviderRecord信息
            // 这是根据PMS解析出的Package信息生成的
            // 此处主要发布的ContentProvider,必须是该Packager已经声明的
            ContentProviderHolder src = providers.get(i);
            ContentProviderRecord dst = r.pubProviders.get(src.info.name);
            ...
            if (dst != null) {
                ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
                // 按名称保存到MProviderMap
                mProviderMap.putProviderByClass(comp, dst);
                
                String names[] = dst.info.authority.split(";");
                for (int j = 0; j <  names.length; j++) {
                    // 按 authority保存到mProviderMap
                    mProviderMap.putProviderByName(names[j], dst);
                }
                // mLaunchingProviders 保存处于启动状态的Provider
                int launchingCount = mLaunchingProviders.size();
                int j;
                boolean wasInLaunchingProviders = false;
                for (j = 0; j < launchingCount; j++) {
                    if (mLaunchingProviders.get(j) == dst) {
                        // 启动完成后,从列表中移除
                        mLaunchingProviders.remove(j);
                        wasInLaunchingProviders = true;
                        j--;
                        launchingCount--;
                    }
                }
                if (wasInLaunchingProviders) {
                    // 取消启动超时的消息
                    mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
                }
                synchronized (dst) {
                    dst.provider = src.provider;
                    dst.proc = r;
                    // 通知
                    dst.notifyAll();
                }
                // 没发布一个ContentProvider,均调整对应进程的oom_adj
                updateOomAdjLocked(r, true);
                // 判断,并在需要的时候更新ContentProvider相关的统计信息
                maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
                        src.info.authority);
            }
        }

        Binder.restoreCallingIdentity(origId);
    }
}

publishContentProvider 函数结束后,一个 ContentProvider 就算正式在系统中注册了。
AMS 的启动过程中,此处注册的是 SettingProvider
此后,Setting数据库相关的操作均由它来管理。

注意到上面的 ContentProvider 注册到 AMS 后,进行了notifyAll 的操作。
举例来说:进程需要查询一个数据库,需要通过进程B中的某个 ContentProvider 来实施。如果 B 还未启动,那么 AMS 就需要先启动 B。在这段时间内,A需要等待B注册启动对应的 ContentProvider。B一旦完成 ContentProvider 的注册,就需要告知A退出等待继续后续的查询工作。

Step SystemServer # systemReady

接下来,我们看看AMS启动的最后一部分:systemReady

com.android.server.SystemServer

private void startOtherServices() {
    ...
    // Step 3.1
    mActivityManagerService.installSystemProviders();
   ...
   mPackageManagerService.systemReady();
    ...
    // Step 3.2
    mActivityManagerService.systemReady(new Runnable() {
        ...
    });
}

在SystemServer中的startOtherServices的最后调用了AMS的systemReady函数
可以看到第一个参数为Runnable。

由于此处代码量很大,所以先分段查看 AMSsystemReady 的处理流程,然后再查看 Runnable 中的处理流程。

Step 3.2.1 阶段一
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
    traceLog.traceBegin("PhaseActivityManagerReady");
    synchronized(this) {
        // 第一次mSystemReady=false
        if (mSystemReady) {
            // If we're done calling all the receivers, run the next "boot phase" passed in
            // by the SystemServer
            if (goingCallback != null) {
                goingCallback.run();
            }
            return;
        }

        // 这一部分主要是调用一些关键服务systemReady相关的函数

        mLocalDeviceIdleController
                = LocalServices.getService(DeviceIdleController.LocalService.class);
        mAssistUtils = new AssistUtils(mContext);
        mVrController.onSystemReady();
        // Make sure we have the current profile info, since it is needed for security checks.
        mUserController.onSystemReady();
        mRecentTasks.onSystemReadyLocked();
        mAppOpsService.systemReady();

        // 系统准备完毕
        mSystemReady = true;
    }

    try {
        sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
                ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
                .getSerial();
    } catch (RemoteException e) {}

    ArrayList<ProcessRecord> procsToKill = null;
    synchronized(mPidsSelfLocked) {
        for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
            // mPidsSelfLocked中保存当前正在运行的所有进程的信息
            ProcessRecord proc = mPidsSelfLocked.valueAt(i);
            // isAllowedWhileBooting中判断FLAG_PERSISTENT标志
            // 在AMS启动完成前,如果没有 FLAG_PERSISTENT 标志的进程已经启动了,将其加入到procsToKill列表中
            if (!isAllowedWhileBooting(proc.info)){
                if (procsToKill == null) {
                    procsToKill = new ArrayList<ProcessRecord>();
                }
                procsToKill.add(proc);
            }
        }
    }

    synchronized(this) {
        if (procsToKill != null) {
            for (int i=procsToKill.size()-1; i>=0; i--) {
                ProcessRecord proc = procsToKill.get(i);
                Slog.i(TAG, "Removing system update proc: " + proc);
                // 关闭 procsToKill中的进程
                removeProcessLocked(proc, true, false, "system update done");
            }
        }

        // Now that we have cleaned up any update processes, we
        // are ready to start launching real processes and know that
        // we won't trample on them any more.
        
        // 进程准备完毕
        mProcessesReady = true;
    }

    ...

    // 根据数据库和资源文件,获取一些配置参数
    retrieveSettings();
    final int currentUserId;
    synchronized (this) {
        // 得到当前的用户Id
        currentUserId = mUserController.getCurrentUserIdLocked();
        // 读取 urigrant.xml,为其中定义的 ContentProvider 配置对指定Uri数据的访问/修改权限
        // 原生的代码中,似乎没有 urigrants.xmls
        // 实际使用的 grant-uri-permission 是分布式定义的
        readGrantedUriPermissionsLocked();
    }


    if (goingCallback != null) goingCallback.run();
    traceLog.traceBegin("ActivityManagerStartApps");

    ...

}

这部分的主要工作:
这一部分的工作主要是

  1. 调用一些关键服务的初始化函数
  2. 杀死那些没有 FLAG_PERSISTENT 却在AMS启动完成前已经存在的进程
  3. 获取一些配置参数。

只有Java进程才会向AMS注册,而一般的Native进程不会向AMS注册,因此这里杀死的进程时Java进程

Step 3.2.2 阶段二
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
    
    ...

    // 调用参数传入的 Runnable对象,SystemServer中有具体的定义
    // Step 3.2.2.1
    if (goingCallback != null) goingCallback.run();
    traceLog.traceBegin("ActivityManagerStartApps");
    
    ...
    
    // 内部循环遍历所有的系统服务的onStartUser接口
    mSystemServiceManager.startUser(currentUserId);

    synchronized (this) {
        // Only start up encryption-aware persistent apps; once user is
        // unlocked we'll come back around and start unaware apps
        // 启动persistent为1的Application所在的进程
        // Step 3.2.2.2
        startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);

        // Start up initial activity.
        mBooting = true;
        // Enable home activity for system user, so that the system can always boot. We don't
        // do this when the system user is not setup since the setup wizard should be the one
        // to handle home activity in this case.
        // 当isSplitSystemUser返回true时,意味着system user和primary user是分离的
        // 这里应该是让system user也有启动 home activity 的权限吧
        if (UserManager.isSplitSystemUser() &&
                Settings.Secure.getInt(mContext.getContentResolver(),
                     Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
            ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
            try {
                AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
                        PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
                        UserHandle.USER_SYSTEM);
            } catch (RemoteException e) {
                throw e.rethrowAsRuntimeException();
            }
        }

        // Step 3.2.2.3 启动 Home
        startHomeActivityLocked(currentUserId, "systemReady");

        try {
            // 发送消息,触发处理Uid错误的Application
            if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
                ...
                mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
            }
        } catch (RemoteException e) {
        }

        // 发送一些广播信息
        ...

        // 这里暂不深入,属于Activity的启动过程,onResume
        mStackSupervisor.resumeFocusedStackTopActivityLocked();

        ... 
    }
}

这部分代码的主要工作:

  1. 通知所有的系统服务执行onStartUser()
  2. 启动persistent=1的Application所在的进程
  3. 启动Home
  4. 执行Activity的onResume
Step 3.2.2.1 SystemServer.systemReady的Runnable回调函数

回调函数定义在 ServerServer#startOtherServices 中,其中会调用大量服务的 onBootPhase 函数、一些对象的systemReady 函数或 systemRunning 函数。

com.android.server.SystemServer

mActivityManagerService.systemReady(() -> {

    // 遍历系统服务startBootPhase启动阶段代码
    mSystemServiceManager.startBootPhase(
            SystemService.PHASE_ACTIVITY_MANAGER_READY);


    try {
        // AMS 启动 NativeCrashListener,监听“/data/system/ndebugsocket”中的信息
        // 实际上就是监听 debuggerd(调试工具) 传入的信息
        mActivityManagerService.startObservingNativeCrashes();
    } catch (Throwable e) {
        reportWtf("observing native crashes", e);
    }


    // No dependency on Webview preparation in system server. But this should
    // be completed before allowring 3rd party
    final String WEBVIEW_PREPARATION = "WebViewFactoryPreparation";
    Future<?> webviewPrep = null;
    if (!mOnlyCore) {
        webviewPrep = SystemServerInitThreadPool.get().submit(() -> {
            Slog.i(TAG, WEBVIEW_PREPARATION);
            TimingsTraceLog traceLog = new TimingsTraceLog(
                    SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
            traceLog.traceBegin(WEBVIEW_PREPARATION);
            ConcurrentUtils.waitForFutureNoInterrupt(mZygotePreload, "Zygote preload");
            mZygotePreload = null;
            mWebViewUpdateService.prepareWebViewInSystemServer();
            traceLog.traceEnd();
        }, WEBVIEW_PREPARATION);
    }

    if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
        traceBeginAndSlog("StartCarServiceHelperService");
        mSystemServiceManager.startService(CarServiceHelperService.class);
        traceEnd();
    }

    // 启动 SystemUi
    try {
        startSystemUi(context, windowManagerF);
    } catch (Throwable e) {
        reportWtf("starting System UI", e);
    }
    
    // 一系列 systemReady
    try {
        if (networkScoreF != null) networkScoreF.systemReady();
    } catch (Throwable e) {
        reportWtf("making Network Score Service ready", e);
    }
    ...
    ...

    // 启动Watchdog
    Watchdog.getInstance().start();

    // Wait for all packages to be prepared
    mPackageManagerService.waitForAppDataPrepared();

    // confirm webview completion before starting 3rd party
    if (webviewPrep != null) {
        ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);
    }

    mSystemServiceManager.startBootPhase(
            SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);


    // 一系列 systemRunning
    try {
        if (locationF != null) locationF.systemRunning();
    } catch (Throwable e) {
        reportWtf("Notifying Location Service running", e);
    }
    ...
    ...

}, BOOT_TIMINGS_TRACE_LOG);
Step 3.2.2.2 AMS # startPersistentApps

启动 persistent 标志的进程

com.android.server.am.ActivityManagerService

private void startPersistentApps(int matchFlags) {
    ...

    synchronized (this) {
        try {
            //从PMS中得到persistent为1的ApplicationInfo
            final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
                    .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
            for (ApplicationInfo app : apps) {
                //由于framework-res.apk已经由系统启动,所以此处不再启动它
                if (!"android".equals(app.packageName)) {
                    //  addAppLocked中将启动application所在进程
                    addAppLocked(app, false, null /* ABI override */);
                }
            }
        } catch (RemoteException ex) {
        }
    }
}

跟进一下 addAppLocked 函数

com.android.server.am.ActivityManagerService

final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
        String abiOverride) {
    //以下是取出或构造出ApplicationInfo对应的ProcessRecord
    ProcessRecord app;
    if (!isolated) {
        app = getProcessRecordLocked(info.processName, info.uid, true);
    } else {
        app = null;
    }

    if (app == null) {
        app = newProcessRecordLocked(info, null, isolated, 0);
        updateLruProcessLocked(app, false, null);
        updateOomAdjLocked();
    }
    ...
    // This package really, really can not be stopped.
    try {
        //通过PKMS将package对应数据结构的StoppedState置为fasle
        AppGlobals.getPackageManager().setPackageStoppedState(
                info.packageName, false, UserHandle.getUserId(app.uid));
    } catch (RemoteException e) {
    } catch (IllegalArgumentException e) {
    }

    if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
        app.persistent = true;
        app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
    }

    if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
        mPersistentStartingProcesses.add(app);
        //启动应用所在进程,将发送消息给zygote,后者fork出进程
        startProcessLocked(app, "added application", app.processName, abiOverride,
                null /* entryPoint */, null /* entryPointArgs */);
    }

    return app;
}

这里最终通过 startProcessLocked 函数,启动实际的应用进程。
Zygote 进程中的 server socket 将接受消息,然后为应用fork出进程

Step 3.2.2.3 AMS # startHomeActivityLocked

启动Home Activity

com.android.server.am.ActivityManagerService

boolean startHomeActivityLocked(int userId, String reason) {
    ...
    Intent intent = getHomeIntent();
    //根据intent中携带的ComponentName,利用PMS得到ActivityInfo
    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);

        //此时home对应进程应该还没启动,app为null
        ProcessRecord app = getProcessRecordLocked(aInfo.processName,
                aInfo.applicationInfo.uid, true);
        if (app == null || app.instrumentationClass == null) {
            intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
            //启动home
            mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
        }
    } else {
        ...
    }
    return true;
}

这里暂时不深究Home Activity启动的具体过程。当启动成功后,会调用Activity#handleResumeActivity方法,最终调用到 ActivityStackSupervisor#activityIdleInternalLocked。

com.android.server.am.ActivityStackSupervisor

final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
        Configuration config) {
    ...
    if (isFocusedStack(r.task.stack) || fromTimeout) {
        booting = checkFinishBootingLocked();
    }
    ...
}

跟进一下 checkFinishBootingLocked 函数

com.android.server.am.ActivityStackSupervisor

private boolean checkFinishBootingLocked() {
    //mService为AMS,mBooting变量在AMS回调SystemServer中定义的Runnable时,置为了true
    final boolean booting = mService.mBooting;
    boolean enableScreen = false;
    mService.mBooting = false;
    if (!mService.mBooted) {
        mService.mBooted = true;
        enableScreen = true;
    }
    if (booting || enableScreen) {、
        //调用AMS的接口,发送消息
        mService.postFinishBooting(booting, enableScreen);
    }
    return booting;
}

最终,AMSfinishBooting 函数将被调用:

com.android.server.am.ActivityManagerService

final void finishBooting() {
    ...
    //以下是注册广播接收器,用于处理需要重启的package
    IntentFilter pkgFilter = new IntentFilter();
    pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
    pkgFilter.addDataScheme("package");
    mContext.registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
            if (pkgs != null) {
                for (String pkg : pkgs) {
                    synchronized (ActivityManagerService.this) {
                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
                                0, "query restart")) {
                            setResultCode(Activity.RESULT_OK);
                            return;
                        }
                    }
                }
            }
       }
    }, pkgFilter);
    ...
    // Let system services know.
    mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);

    //以下是启动那些等待启动的进程
    synchronized (this) {
        // Ensure that any processes we had put on hold are now started
        // up.
        final int NP = mProcessesOnHold.size();
            if (NP > 0) {
                ArrayList<ProcessRecord> procs =
                        new ArrayList<ProcessRecord>(mProcessesOnHold);
                for (int ip=0; ip<NP; ip++) {
                    ...
                    startProcessLocked(procs.get(ip), "on-hold", null);
                }
            }
        }
    }
    ...
    if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
        // Start looking for apps that are abusing wake locks.
        //每5min检查一次系统各应用进程使用电量的情况,如果某个进程使用WakeLock的时间过长
        //AMS将关闭该进程
        Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
        mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);

        // Tell anyone interested that we are done booting!
        SystemProperties.set("sys.boot_completed", "1");
        ...
        //此处从代码来看发送的是ACTION_LOCKED_BOOT_COMPLETED广播
        //在进行unlock相关的工作后,mUserController将调用finishUserUnlocking,发送SYSTEM_USER_UNLOCK_MSG消息给AMS
        //AMS收到消息后,调用mUserController的finishUserUnlocked函数,经过相应的处理后,
        //在mUserController的finishUserUnlockedCompleted中,最终将会发送ACTION_BOOT_COMPLETED广播
        mUserController.sendBootCompletedLocked(...);
        ...
    }
}

最终AMS启动 HomeActivity 结束,并发送 ACTION_BOOT_COMPLETED 广播时,AMS的启动过程告一段落。


总结
对于整个AMS
启动过程来说,本文涉及的内容只是其中极小一部分。
整个过程,可以将AMS的启动过程分为四步

  1. 创建出 SystemServer 进程的 Android 运行环境
    这个流程,创建SystemServer进程对应的ActivityThread和ContextImpl,构成Android运行环境
    AMS后续工作依赖SystemServer在此创建出的运行环境

  2. 完成AMS的初始化和启动
    这个流程,调用了AMS的构造函数和start函数,完成AMS一些初始化工作

  3. 将SystemServer进程纳入到AMS的管理体系
    这个流程,AMS加载了SystemServer中framework-res.apk的信息,并启动和注册了SettingsProvider.apk。涉及了ContentProvider的安装。

  4. AMS启动完毕后才能进行的工作
    这个流程,AMS调用 systemReady函数,通知系统的其他服务和进程,可以进行对应的工作。
    并且,Home Activity被启动了,当Home Activity被加载完成后,最终会触发ACTION_BOOT_COMPLETED广播。

AMS 流程
  1. 创建 system 进程的运行环境,一个 ActivityThread 主线程,一个和系统进程相关的 Context 对象
  2. 调用 AMS 的构造方法,对必要的内容进行初始化
  3. 将 AMS 注册到 ServiceManager 中,同时对 system 进程创建一个 ProcessRecord 对象,并设置 Contextapplicationframework-resapplication 对象。由于 AMSAndroid 世界的进程管理和调度中心,尽管 system 贵为系统进程,也要将其并入 AMS 的管理范围
  4. system 进程加载 SettingProvider
  5. 调用 systemReady 方法做系统启动完毕前的最后一些扫尾工作。最 HomeActivity 将呈现在用户面前

参考资料

Android-0.AMS初始化和启动简介

Android 7.0 ActivityManagerService(1) AMS的启动过程

上一篇下一篇

猜你喜欢

热点阅读