美文网首页
AMS系列①—AMS的启动

AMS系列①—AMS的启动

作者: leap_ | 来源:发表于2020-10-19 21:31 被阅读0次

    AMS作为Android FrameWork中最核心的一个部分,是应用层开发者进阶的里程碑,本文是AMS专栏的第一篇文章,介绍AMS的启动相关:

    在学习AMS之前,需要掌握一些基础知识:

    在学习完上面的内容后,我们可以知道AMS的启动是由SystemServer进程发起的:

    AMS的入口方法SystemServer的main()做了两件事:

    • 调用CreateSystemContext()创建SystemContext
    • 开启三类服务:引导服务,核心服务,其他服务

    1. SystemServer.createSystemContext():

        private void createSystemContext() {
            ActivityThread activityThread = ActivityThread.systemMain();
        }
    

    ActivityThread.systemMain():

        public static ActivityThread systemMain() {
            ActivityThread thread = new ActivityThread();
            thread.attach(true, 0);
            return thread;
        }
    

    在SystemMain中,首先创建了一个SystemServer进程的ActivityThread,没错,这就是用户进程的入口main的那个ActivityThread,所以从某种意义上讲,我们也可以将SystemServer进程看成一个App;

    调用了ActivityThread的attach(),注意,这里传入的是true,而我们正常的App传入的是false,这个字段表示是否是系统进程(SystemServer进程):

    ActivityThread.attach():

        private void attach(boolean system, long startSeq) {
    ...
            if (!system) {    //  如果是正常App进程,传入false
    ...
                final IActivityManager mgr = ActivityManager.getService();
                try {
                    mgr.attachApplication(mAppThread, startSeq);
                } 
    ...
            } else {   //  如果是SystemServer进程,传入true
    ...
                try {
                    mInstrumentation = new Instrumentation();
                    mInstrumentation.basicInit(this);
                    ContextImpl context = ContextImpl.createAppContext(
                            this, getSystemContext().mPackageInfo);
                    mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                    mInitialApplication.onCreate();
                } 
            }
        }
    

    如果是正常的APP,那么进入if逻辑,调用AMS的代理发起一次Binder消息,实际调用AMS的attachApplication();
    在本次情况中是由SystemServer进程发起的,进入else逻辑:

    • 调用ContextImpl.createAppContext()创建App Context
    • 注意上一个方法,传入了一个getSystemContext().mPackageInfo参数
    • 调用makeApplication创建Application

    我们先来看传入的参数:

    ActivityThread.getSystemContext()

        public ContextImpl getSystemContext() {
            synchronized (this) {
                    mSystemContext = ContextImpl.createSystemContext(this);
        }
    

    getSystemContext()调用了ContextImpl的createSystemContext():

    ContextImpl.createSystemContext():

        static ContextImpl createSystemContext(ActivityThread mainThread) {
            LoadedApk packageInfo = new LoadedApk(mainThread);
            ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
                    null);
            context.setResources(packageInfo.getResources());
            return context;
        }
    

    ContextImpl有一系列的创建Context的static 方法:



    在这里创建了SystemContext,Context的具体作用就是用来获取资源,比如你的Activity需要使用apk里面的资源,而系统SystemServer也需要使用系统预设的资源文件,所以在这里也创建了一个Context对象;

    那么Context是如何获取资源的呢?答案是LoadedApk这个类,LoadedApk是apk文件在内存中的存在形式
    所以一般ApplicationContext或者ActivityContext都会持有它对应的apk文件的内存形式LoadedApk对象;那么我们的SystemServer是跟哪个APK绑定呢???看下面这张图就明白了:

    虽然它是一个LoadedAPK对象,但是并没有对应apk文件,它存在的意义就是为SystemContext服务,为它提供获取系统资源的能力;注意倒数第二第三行,SystemClassLoader,SystemResource,如果是通过其他构造方法创建的LoadedApk,就不会有这个值,他们是通过对应apk文件解析出来的数据;

    至此,我们的SystemContext创建完毕,回到ActivityThread.attach():这一步,参数看好了,参数就是SystemContext的LoadedApk,就是那个没有apk的LoadedAPK;

    ContextImpl.CreateAppContext:

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

    在这里因为传入的LoadedAPK是被阉割的LoadedAPK对象,所以这个ApplicationContext,本质上和SystemContext一样,他们的resource都是System Resource;

    context.mPackageInfo.makeApplication(true, null):

       public Application makeApplication(boolean forceDefaultAppClass,
                Instrumentation instrumentation) {
    ...
                ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
                app = mActivityThread.mInstrumentation.newApplication(
                        cl, appClass, appContext);
            } 
    ...
            return app;
        }
    

    mInstrumentation.newApplication()

        public Application newApplication(ClassLoader cl, String className, Context context)
                throws InstantiationException, IllegalAccessException, 
                ClassNotFoundException {
            Application app = getFactory(context.getPackageName())
                    .instantiateApplication(cl, className);
            app.attach(context);
            return app;
        }
    

    makeApplication的逻辑就是创建Application对象,然后调用Application的attach方法:

        /* package */ final void attach(Context context) {
            attachBaseContext(context);
            mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
        }
    
        protected void attachBaseContext(Context base) {
            if (mBase != null) {
                throw new IllegalStateException("Base context already set");
            }
            mBase = base;
        }
    

    保存Application Context 和 LoadedApk到Application

    至此SystemServer创建System Context的操作分析完毕,下面分析SystemServer的run()中开启三类服务中关于AMS的逻辑

    SystemServer.startBootstrapServices():

        private void startBootstrapServices() {
    ...
           mActivityManagerService = mSystemServiceManager.startService(
                    ActivityManagerService.Lifecycle.class).getService();
    
           mActivityManagerService.setInstaller(installer);
    
            mActivityManagerService.initPowerManagement();
    
            mActivityManagerService.setSystemProcess();
        }
    

    在启动引导服务startBootstrapServices这个方法中,涉及AMS的逻辑主要做了四件事:

    1. 创建AMS实例
    2. 设置installer,App安装器
    3. 初始化PMS
    4. 调用setSystemProcess()

    1. startService(ActivityManagerService.Lifecycle.class).getService();

    startService()传入了一个AMS的内部类Lifecycle的Class对象,会创建一个Lifecycle的实例,接着这个Lifecycle会调用自己的getService方法获取AMS实例:

            public Lifecycle(Context context) {
                super(context);
                mService = new ActivityManagerService(context);   
            }
            public ActivityManagerService getService() {
                return mService;
            }
    

    下面看一下AMS的构造方法,AMS的构造方法中,做了很多事情:

       public ActivityManagerService(Context systemContext) {
    ...
            // 前台服务线程 
            mHandlerThread = new ServiceThread(TAG,
                    THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
    
                 //  后台服务线程
                sKillThread = new ServiceThread(TAG + ":kill",
                        THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
    
             // CPU线程
            mProcessCpuThread = new Thread("CpuTracker") ;
    
             //  AMS家族:
            mConstants = new ActivityManagerConstants(this, mHandler);
            mServices = new ActiveServices(this);
            mStackSupervisor = createStackSupervisor();
            mActivityStartController = new ActivityStartController(this);
    
            //  开启 watch dog
            Watchdog.getInstance().addMonitor(this);
            Watchdog.getInstance().addThread(mHandler);
    
             // 创建 AppOpsService , Android原生应用程序权限管理相关
            mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
    
            //创建进程状态服务,监听进程转发服务
            mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
    
            //创建电量状态服务
            mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
    
    
        }
    

    在AMS的构造方法中,大概做了以下几件事:

    1. 创建各个工作线程,前台服务线程,后台服务线程,CPU线程
    2. 实例化AMS家族成员,ActivityManagerConstants,ActiveServices,StackSupervisor,ActivityStartController,这些在后续会详细介绍;
    3. 开启各种服务,watch dog,Appops,ProcessStatsService,BatteryStatsService
    • 软件看门狗来监控SystemServer中的线程。一旦发现问题,WatchDog会杀死SystemServer进程。SystemServer的父进程Zygote接收到SystemServer的死亡信号后,会杀死自己。Zygote进程死亡的信号传递到Init进程后,Init进程会杀死Zygote进程所有的子进程并重启Zygote。这样整个手机相当于重启一遍。通常SystemServer出现问题和kernel并没有关系,所以这种“软重启”大部分时候都能够解决问题。而且这种“软重启”的速度更快,对用户的影响也更小。
    至此,第一步AMS的实例化分析完毕,步骤2 和 步骤3 是设置APk安装器和初始化PMS,不做过多介绍,下面详细看下步骤4setSystemProcess()

    4 mActivityManagerService.setSystemProcess();

        public void setSystemProcess() {
            try {
                ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
                        DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
                ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
                ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
                        DUMP_FLAG_PRIORITY_HIGH);
                ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
                ServiceManager.addService("dbinfo", new DbBinder(this));
                if (MONITOR_CPU_USAGE) {
                    ServiceManager.addService("cpuinfo", new CpuBinder(this),
                            /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
                }
                ServiceManager.addService("permission", new PermissionController(this));
                ServiceManager.addService("processinfo", new ProcessInfoService(this));
    
                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                        "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
                mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
    
                synchronized (this) {
                    ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
                    app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
                }
            } 
    
            // Start watching app ops after we and the package manager are up and running.
            mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null);
        }
    

    在AMS的setSystemProcess()中主要做了四件事:

    1. 添加各种服务到ServiceManager中:this(自己AMS服务),内存,图像,权限,cpu,进程,相关服务
    2. installSystemApplicationInfo
    3. 创建ProcessRecord对象
    4. 调用AppOps服务的startWatch方法开启对应用程序包给定权限的监听;
    步骤2:installSystemApplicationInfo():
        public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
            synchronized (this) {
                getSystemContext().installSystemApplicationInfo(info, classLoader);
                getSystemUiContext().installSystemApplicationInfo(info, classLoader);
    
                // give ourselves a default profiler
                mProfiler = new Profiler();
            }
        }
    

    步骤2做了两件事:

    • 将ApplicationInfo对象设置给SystemContext
    • 创建Profiler对象,用于性能统计

    至此SystemService开启引导服务中AMS相关的逻辑分析完毕;


    SystemServer.startOtherServices():

    mActivityManagerService.systemReady(() -> {
                mSystemServiceManager.startBootPhase(
                try {
                    mActivityManagerService.startObservingNativeCrashes();
                }  
    
        public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
    
    
                mVrController.onSystemReady();
                mUserController.onSystemReady();
                mRecentTasks.onSystemReadyLocked();
                mAppOpsService.systemReady();
                mSystemReady = true;
    
                startHomeActivityLocked(currentUserId, "systemReady");
        }
    
    

    在startOtherServices()中,AMS的主要逻辑就是调用了SystemReady()开启一个Activity,开启Activity的内容后期再讲,会设计AMS的大家族;

    相关文章

      网友评论

          本文标题:AMS系列①—AMS的启动

          本文链接:https://www.haomeiwen.com/subject/uirfmktx.html