Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动

Posted CrazyMo_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动相关的知识,希望对你有一定的参考价值。

文章大纲

引言

前文章介绍到Zygote进程会把SystemServer进程启动,在SystemServer的启动过程中会把Java层系统服务都一一启动,ActivitityManagerService 就是在这时候被启动的,而SystemServer的启动流程可以参考我之前的文章,这里只分析与AMS相关的启动流程。

  • 初始化 SystemContext
  • 创建SystemServiceManager 对象,用来启动后面的服务
    启动系统服务,共分为三种系统服务:系统引导服务(Boot Service)、核心服务(Core Service)和其他服务(Other Service)
  • 在引导服务(Boot Service)中启动ATM、AMS服务
  • 在其他服务(Other Service)中完成AMS的最后工作systemReady

基于android 28 ,为了阅读,本文约定方法表示Java的,而函数表示Native层概念,本章只涉及到AMS 的启动相关知识,其他AMS相关的敬请关注后续文章,仅供参考

一、ActivitityManagerService 概述

ActivitityManagerService(AMS) 服务由SystemServer在启动过程中去启动的,是运行在SystemServer进程中,负责管理Android 四大组件以及所有用户进程管理和调度。AMS 和Zygote 通过sokect 通信完成用户进程的创建,在Framework 内部通过Binder 与其他用户进程进行通信。总之,AMS 管理Android 系统中所有的非Zygote的应用进程。

二、ActivityManagerService 体系结构概述

从一定程度上来说Android 就是一个微服务体系的操作系统,即Android =Linux + Framework 定制各种服务。而在Android 中系统核心服务都是采用Binder 服务的架构,当某个进程需要访问某个系统服务时首先得通过ServiceManager 获取其对应的Binder对象,从而调用对应的方法,至于中间的通信细节全部由Binder 通信去完成。

Android 应用层我们使用Binder 有两种方式:一种是通过AIDL 自动生成,另一种则是自己去继承Binder实现具体的通信框架代码,核心服务都是采用后者。

1、android.app.IActivityManager

IActivityManager 是AMS的核心功能接口,定义了AMS 的所有功能,由于需要支持跨进程调用,因而继承了IInterface接口。

2、IActivityManager.Stub/android.app.ActivityManagerNative.java

Android低版本实现是ActivityManagerNative,高版本8.0后是以标准AIDL 语法自动生成的IActivityManager.Stub

IActivityManager.Stub/ActivityManagerNative 是一个抽象类除了实现AMS 的核心功能之外,还需要实现Binder 通信框架的功能。它提供了服务接口和Binder接口的相互转化功能,并在内部存储服务代理对像,并提供了getDefault方法返回服务代理对象。

3、android.app.ActivityManagerProxy

Android低版本是单独实现,高版本8.0后是以标准AIDL 语法自动生成的。

ActivityManagerProxy 是作为ActivityManagerNative 的嵌入类(非内部类)实现,是IActivityManager的代理Binder对象,用于与Server端提供的系统服务进行进程间通信

4、com.android.server.am.ActivityManagerService

ActivityManagerService继承自ActivityManagerNative 是提供给其他类调用的功能入口,提供Server端的系统服务。

5、android.app.ActivityManager

ActivityManager 相当于是对ActivityManagerProxy 的封装,间接持有了IActivityManager 引用,通过延迟初始化的方式来得到ActivityManagerProxy 的引用,从而通过这个引用调用其对应的方法。ActivityManager内部通过调用ActivityManagerNative的getDefault方法,可以得到一个ActivityManagerProxy对像的引用,进而通过该代理对像调用远程服务的方法

    public static IActivityManager getService() 
        return IActivityManagerSingleton.get();
    

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() 
                @Override
                protected IActivityManager create() 
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                
            ;

延迟单例的实现:

public abstract class Singleton<T> 
    private T mInstance;

    protected abstract T create();

    public final T get() 
        synchronized (this) 
            if (mInstance == null) 
                mInstance = create();
            
            return mInstance;
        
    

三、ActivityManagerService 相关的重要类概述

1、ProcessRecord

  • ApplicationInfo info——AndroidManifest.xml中定义的Application信息

  • boolean isolated——是否是分离进程

  • int uid——进程uid

  • int userId——android多用户机制时系统用户的id,类似windows可以登录很多用户一样

  • String processName——进程名字,默认情况下是包名

  • IApplicationThread thread——是ApplicationThread的客户端,AMS就是通过这
    个对象给apk进程发送异步消息的(管理四大组件的消息),所以只有这个对象不为空的情况下,
    才代表apk进程可以使用了

  • int pid——进程的pid

  • ArraySet < String > pkgList——进程中运行的包

  • ArraySet < String > pkgDeps——进程运行依赖的包

  • ArrayList< ActivityRecord > activities——进程启动的所有的activity组件记录表

  • ArraySet< ServiceRecord >services——进程启动的所有的service组件记录表

  • ArraySet< ServiceRecord > receivers——广播接收器的记录表

  • ArraySet< ConnectionRecord > connections——进程里所有的Bind service的客户端信息

  • ArrayMap<String, ContentProviderRecord> pubProviders——进程发布到AMS 的ContentProvider和名字的映射

    pub即publish(发布)的意思,ContentProvider需要安装然后把自己发布到系统(AMS)中后,才能使用,安装指的是apk进程加载ContentProvider子类、初始化、创建数据库等过程,发布是将ContentProvider的binder客户端注册到AMS中。

  • ArrayList< ContentProviderConnection > conProviders ——ContentProviderConnection容器,使用ContentProvider的客户端记录表

  • BroadcastRecord curReceiver——当前进程正在执行的广播

  • int maxAdj——进程的adj上限(adjustment)

  • int curRawAdj——当前正在计算的adj,这个值有可能大于maxAdj

  • int setRawAdj——上次计算的curRawAdj设置到lowmemorykiller系统后的adj

  • int curAdj——当前正在计算的adj,这是curRawAdj被maxAdj削平的值

  • int pssProcState——pss进程状态

  • VSS( Virtual Set Size )虚拟耗用内存(包含共享库占用的内存)

  • RSS(Resident Set Size )实际使用物理内存(包含共享库占用的内存)

  • PSS(Proportional Set Size )实际使用的物理内存(比例分配共享库占用的内存)

  • USS-(Unique Set Size )进程独自占用的物理内存(不包含共享库占用的内存)

一般来说内存占用大小是VSS >= RSS >= PSS >= USS

  • .long initialIdlePss——初始化pss

  • .long lastPss——上次pss

  • .long lastSwapPss——上次SwapPss数据

  • long lastCachedPss——上次CachedPss数据

  • long lastCachedSwapPss——上次CachedSwapPss数据

  • long lastActivityTime——上次使用时间

  • long lastStateTime——上次设置进程状态的时间

  • long fgInteractionTime——变成前台的时间

  • IBinder.DeathRecipient deathRecipient——apk进程退出运行的话,会触发这个对象的
    binderDied()方法,来回收系统资源

  • boolean crashing——进程已经crash

  • Dialog crashDialog——crash对话框

  • Dialog anrDialog——anr显示对话框

  • String waitingToKill:后台进程被kill原因

Instrumentation 也可以说是apk的一个组件,如果我们不提供的话,系统会默认使用Instrumentation.java类,按照我们一般的理解,UI 线程控制activity的生命周期,是是直接调用Activity类的方法,实质上缺少UI线程调用的是Instrumentation的方法,由它在调用Activity涉及生命周期的方法,所有如果我们覆写了Instrumentation的这些方法,就可以了解所有的Activity的生命周期了.

  • ComponentName instrumentationClass——AndroidManifest.xml中定义的instrumentation信 息
  • ApplicationInfo instrumentationInfo——instrumentation应用信息
  • String instrumentationProfileFile——instrumentation配置文件
  • IInstrumentationWatcher instrumentationWatcher——instrumentation监测器
  • BatteryStatsImpl mBatteryStats——电量信息
  • BatteryStatsImpl.Uid.Proc curProcBatteryStats——当前进程电量信息
  • boolean debugging——处于调试中
  • boolean waitedForDebugger——等待调试
  • Dialog waitDialog——等待对话框
  • ArraySet< ServiceRecord > executingServices:正在运行(executing)的ServiceRecord是怎么定义的?首先需要明确的是系统是怎么控制组件的?发送消息给apk进程,apk进程处理消息,上报消息完成,这被定义为一个完整的执行过程,因此正在执行(executing)被定义为发送消息到上报完成这段时间

2、四大组件的内存映射信息类

在Android 中 进程的概念被弱化了,传统的Linux下进程是程序执行的再提,进程退出也意味着应用关闭,但是在Android中,进程只是组件运行的一个容器,当系统需要运行一个组件时,才启动包含它的进程,而当组件不再使用,进程也会被关闭,组件运行才是进程存在的意义,由于Android系统进程间的无缝结合,所以系统需要控制到组件级别,所有的组件信息都需要映射到系统。

  • ActivityRecord记录对应一个Activity的信息
  • ServiceRecord记录对应一个Service的信息
  • ConnectionRecord记录对应一个Bind service的客户端信息
  • ReceiverList对应处理同一事件的一组广播
  • ContentProviderRecord记录对应一个ContentProvider信息
  • ContentProviderConnection对应一个进程中的所有ContentProvider客户端.

3、Activity 管理相关的类

ActivityStackSupervisor 管理ActivityStack,ActivityStack 内部包含多个TaskRecord 列表,TaskRecord内部包含报个ActivityRecord。

2.1、ActivityRecord

ActivityRecord(An entry in the history stack, representing an activity)Activity栈栈中的一个条目,代表一个Activity的内存对象,ActivityRecord中存在着大量的成员变量描述一个Activity的所有信息。 其中ActivityRecord中的成员变量task表示其所在的TaskRecord。

\\frameworks\\base\\services\\core\\java\\com\\android\\server\\am\\ActivityStarter.java

2.2、TaskRecord

TaskRecord内部维护一个 ArrayList< ActivityRecord > 用来保存ActivityRecord,其中TaskRecord中的mStack表示其所在的ActivityStack, startActivity()时也会创建一个TaskRecord,代表一个任务的的内存对象。

\\frameworks\\base\\services\\core\\java\\com\\android\\server\\am\\TaskRecord.java

2.3、ActivityStarter

Activity 的管理类。

frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

2.4、ActivityStack

ActivityStack内部通过 ArrayList维护了 TaskRecord 列表,还持有ActivityStackSupervisor对象,ActivityStack是由ActivityStackSupervisor来创建的,实际ActivityStackSupervisor就是用来管理ActivityStack的。

2.5、ActivityStackSupervisor

ActivityStackSupervisor(Run all ActivityStacks through this )就是用来管理ActivityStack。ActivityStackSupervisor内部有两个不同的ActivityStack对象——mHomeStack、mFocusedStack,用来管理不同的任务。 ActivityStackSupervisor内部包含了创建ActivityStack对象的方法。 AMS初始化时会创建一个ActivityStackSupervisor对象.

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

四、ActivityManagerService 启动前的环境初始化

而在SystemServer的run函数中,在启动AMS之前,还做了其他的环境初始化工作:

  • 创建初始化Looper
  • 加载android_servers本地库初始化和启动本地服务
  • 调用了createSystemContext方法,主要用于初始化 System Context和SystemUi Context,并设置主题当SystemServer ,当调用createSystemContext()完毕后:
    • 得到了一个ActivityThread对象,它代表当前进程 (此时为系统进程) 的主线程;
    • 得到了一个Context对象,对于SystemServer而言,它包含的Application运行环境与framework-res.apk有关。
  • 创建了一个SystemServiceManager 对象管理系统服务的创建、启动和处理生命周期事件。
private void run() 
        try 
             // 设置虚拟机的路径
            SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
          	...
           ...
               //初始化Looper
            Looper.prepareMainLooper();

            // Initialize native services.
            System.loadLibrary("android_servers");
            ...
            // Initialize the system context.
            createSystemContext();

            // Create the system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
         
    	...
    

在SystemServer的run函数中,在启动AMS之前,调用了createSystemContext函,主要用来是初始化 System Context和SystemUi Context,并设置主题.

private void createSystemContext() 
    ActivityThread activityThread = ActivityThread.systemMain();
    //获取System Context上下文对象
    mSystemContext = activityThread.getSystemContext();
    //设置系统主题
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
 
    //获取SystemUI Context
    final Context systemUiContext = activityThread.getSystemUiContext();
    //设置systemUI 主题
    systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);

五、ActivityManagerService 服务的启动和运行。

1、SystemServer#mian方法中通过ActivityManagerService #main方法触发AMS启动

    /**
     * The main entry point from zygote.
     */
    public static void main(String[] args) 
        new SystemServer().run();
    
    private void run() 
        try 
        // Start services.
        try 
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
         catch (Throwable ex) 
            Slog.e("System", "************ Failure starting system services", ex);
        
        ...
        Looper.loop();
    

2、com.android.server.SystemServer#startBootstrapServices 方法触发创建和注册到ServiceManager

    private void startBootstrapServices() 
        // 通过Socket去与Linux 底层installd 进程去通信完成安装任务
        Installer installer = mSystemServiceManager.startService(Installer.class);

        // Activity manager runs the show.
        mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
        ...
        // Initialize attribute cache used to cache resources from packages.
        AttributeCache.init(mSystemContext);
        // Set up the Application instance for the system process and get started.
        mActivityManagerService.setSystemProcess();
         ...
           

3、在com.android.server.SystemServiceManager#startService方法里反射AMS 对象并启动

SystemServiceManager 是管理com.android.server.SystemService 系统服务的创建、启动和处理生命周期事件的管理里类,而ServiceManager 是Binder 体系里管理服务端的服务类,位于\\frameworks\\base\\services\\core\\java\\com\\android\\server\\SystemServiceManager.java。

在startBootstrapServices 方法里传入的并不直接是ActivityManagerService.class 而是传入了一个名为Systemcom.android.server.am.ActivityManagerService.Lifecycle的class,

public <T extends SystemService> T startService(Class<T> serviceClass) 
    try 
        final String name = serviceClass.getName();
        // Create the service.
        final T service;
        try 
            Constructor<T> constructor = serviceClass.getConstructor(Context.class);
            service = constructor.newInstance(mContext);
         
   		  //@link final ArrayList<SystemService> mServices = new ArrayList<SystemService>(); 把SystemService 对象缓存起来
        mServices.add(service);
        // Start it.
        try 
            // AMS#onStart
            service.onStart();
         catch (RuntimeException ex) 
            throw new RuntimeException("Failed to start service " + name
                    + ": onStart threw an exception", ex);
        
        return service;
     finally 
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    

是通过反射调用ActivityManagerService.Lifecycle的构造函数,在其构造函数内部调用了AMS的构造方法直接new出了AMS对象。

为什么不直接反射AMS 的构造函数呢?可以好好思考一下!


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

    public Lifecycle(Context context) 
        super(context);
        mService = new ActivityManagerService(context);
    

    @Override
    public void onStart() 
        mService.start();
    

    public ActivityManagerService getService() 
        return mService;
    

3.1、ActivityManagerService 的构造方法

  • \\frameworks\\base\\services\\core\\java\\com\\android\\server\\am\\ActiveServices.java
  • \\frameworks\\base\\services\\core\\java\\com\\android\\server\\am\\BroadcastQueue.java
  • \\frameworks\\base\\services\\core\\java\\com\\android\\server\\am\\ProviderMap.java

ActivityManagerService 构造方法里主要是完成了四大基础组件的管理对象和线程通信相关初始化工作:

  • 获取SystemServer 进程中的ActivityThread对象
  • 创建通过消息处理机制与其他线程通信的Handler对象
  • 创建Handler和Handler 对象用于线程间通信
  • 创建广播的管理对象BroadcastQueue,主要就是几个List集合、数组存储广播
  • 创建Service 服务的管理对象ActiveServices
  • 创建内容提供者的管理对象ProviderMap,ContentProviderRecord 封装了IContentProvider Binder接口并被Provider 管理。
  • 创建/data/system/目录
  • 创建Activity 的管理对象
  • 把AMS 对象添加到Android 自己实现的WatchDog 机制中监控

PMS的构造函数主要初始化一些成员变量并在/data/system下面建立一些文件(夹)供系统统计数据用,现将一些文件及其作用列在下面的表格中:

Service文件路径说明
BatteryStatsService/data/system/batterystats.bin管理电池使用状态
ProcessStatsService/data/system/procstats管理进程状态
UsageStatsService/data/system/usagestats管理用户使用状态
AppOpsService/data/system/appops.xml管理进程状态
AtomicFile/data/system/urigrants.xml管理系统URI权限
public ActivityManagerService(Context systemContext) 
        mContext = systemContext;
        ...
        // 获取在当前线程(即SystemServer进程)中的ActivityThread 对象
        mSystemThread = ActivityThread.currentActivityThread();
    	 //创建通过消息处理机制与其他线程通信的Handler对象
        mHandlerThread = new ServiceThread(TAG,android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
        mHandlerThread.start();
        mHandler = new MainHandler(mHandlerThread.getLooper());
        //专门处理展示UI相关的Handler对象
        mUiHandler = new UiHandler();
    	  //创建广播管理数据结构,创建 BroadcastQueue 前台广播对象,处理超时时长是 10s
        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
                "foreground", BROADCAST_FG_TIMEOUT, false);
    // BroadcastQueue 后台广播对象,处理超时时长是 60s
        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
                "background", BROADCAST_BG_TIMEOUT, true);
    	//@link final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
        mBroadcastQueues[0] = mFgBroadcastQueue;
        mBroadcastQueues[1] = mBgBroadcastQueue;
// 创建 ActiveServices 对象,用于管理 ServiceRecord 对象
        mServices = new ActiveServices(this);
    //创建 ProviderMap 对象,用于管理 ContentProviderRecord 对象
        mProviderMap = new ProviderMap(this);
        mAppErrors = new AppErrors(mContext, this);

        // 获取/data/的路径
        File dataDir = Environment.getDataDirectory();
    	// 创建data/system/目录
        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);
			//进程状态保存在data/system/procstats/pid/目录下,提供dump服务的基础
        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
    		...
        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));

        mUserController = new UserController(this);
		 //从系统属性系统中获取对应的OpenGLES的版本
        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
			//创建Activity 管理对象
        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
    		//创建最近打开任务对象
        mRecentTasks = new RecentTasks(this, mStackSupervisor);
		  //统计CPU ,如果写入太频繁就wait 
        mProcessCpuThread = new Thread("CpuTracker") 
            @Override
            public void run() 
                    ...
                
            
        ;
		//把AMS 服务加到Android 自己实现的软件WatchDog 监控中
        Watchdog.getInstance().addMonitor(this);
        Watchdog.getInstance().addThread(mHandler);
            ...
      
    

3.2、ActivityManagerService#start 方法

AMS 对象被反射创建完毕之后,通过ActivityManagerService.Lifecycle触发ActivityManagerService#start方法执行。

    private void start() 
        Process.removeAllProcessGroups();
        mProcessCpuThread.start();
			//发布电池服务等其他服务
        mBatteryStatsService.publish(mContext);
        //发布 管理系统URI权限
        mAppOpsService.publish(mContext);
        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
    

至此AMS 启动完成。

以上是关于Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动的主要内容,如果未能解决你的问题,请参考以下文章

Android 进阶——系统启动之SystemServer创建并启动Installer服务

Android 进阶——系统启动之SystemServer创建并启动Installer服务

Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动

Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动

Android 进阶——系统启动之Framework 核心ActivitityManagerService服务启动

Android 进阶——系统启动之核心SystemServer进程启动详解