ActivityManagerService启动解析

我们知道,在zygote进行初始化时,会调用startSystemServer方法来初始化各种servcie,其中包括ActivityMangerService,现在我们就来看看ActivityMangerService是如何初始化的。我们从AMS被初始化的地方开起,也就是 SystemServer这个类

它的源码位于frameworks/base/services/java/com/android/server/SystemServer.java,这个类主要的做的事情有这几件

  • ①初始化native service
  • ②初始化系统上下文
  • ③创建system service manager
  • ④startBootstrapServices
  • ⑤startCoreServices
  • ⑥startOtherServices

我们再来看看SystemServer的启动时序图
这里写图片描述
下面再大致分析一下SystemServer的源码

    private void run() {
            ……     

            //1、虚拟机内存初始化
            VMRuntime.getRuntime().clearGrowthLimit();
            VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

            ……

            //2、创建消息队列
            Looper.prepareMainLooper();

            //3、初始化 native services.
            System.loadLibrary("android_servers");


            //4、初始化系统上下文
            createSystemContext();

            //5、创建system service manager.
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            // 为初始化任务准备线程池
            SystemServerInitThreadPool.get();

        // Start services.
        try {
            //6、启动BootstrapServices,CoreServices,OtherServices
            traceBeginAndSlog("StartServices");
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }
        // Loop forever.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

现在我们已经了解了SystemSever大致所做的事情,这篇文章讲的是ActivityManagerService,所以对SystemSever便不再详细的讲解,从时序图中看到ActivityManagerService是从初始化系统上下时启动的,我们便从源码中的4,初始系统上下文这一点开始进一步的讲解,createSystemContext方法具体内容如下

private void createSystemContext() {
   ActivityThread activityThread = ActivityThread.systemMain();
   mSystemContext = activityThread.getSystemContext();
   mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

   final Context systemUiContext = activityThread.getSystemUiContext();
   systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}

可以看到,里面调用的是ActivityThread的systemMain方法,然后获取的是ActivityThread的SystemContext,ActivityThread相当于是每个应用的应用的主线程,负责调度和执行activities、broadcasts和其它操作。我们接着看看systemMain方法

public static ActivityThread systemMain() {
   // The system process on low-memory devices do not get to use hardware
   // accelerated drawing, since this can add too much overhead to the
   // process.
   if (!ActivityManager.isHighEndGfx()) {
       ThreadedRenderer.disable(true);
   } else {
       ThreadedRenderer.enableForegroundTrimming();
   }
   ActivityThread thread = new ActivityThread();
   thread.attach(true);
   return thread;
}

这个方法实际就是new了一个ActivityThread,并且调用了attach方法,attach方法做的事情主要有以下几件
①判断时候从系统启动,如果不是从系统系统,则ApplicationThread把mAppThread attach到系统进程system_process,以便system_process控制当前应用的ActivityThread,这一步操作我们之后再详解,因为现在从系统启动的ActivityThread,所以attach方法实际会执行以下几步操作

  • 创建Instrumentation,Instrumentation是Android中的一个工具类
  • 执行ContextImpl.createAppContext方法,也就是创建Context
  • 执行context.mPackageInfo.makeApplication方法,创建InitialApplication
  • 调用InitialApplication.onCreate()

②注册Configuration变化的回调通知

下面我们看看attach方法的源码

 private void attach(boolean system) {
     //将创建出的ActivityThread保存在类的静态变量sCurrentActivityThread,AMS中的大量操作将会依赖于这个ActivityThread
     sCurrentActivityThread = this;
     mSystemThread = system;
     if (!system) {
         //非系统启动
         ……
         final IActivityManager mgr = ActivityManager.getService();
         try {
             //将mAppThread关联到ActivityManager中
             mgr.attachApplication(mAppThread);
         } catch (RemoteException ex) {
             throw ex.rethrowFromSystemServer();
         }

         ……
     } else {
         //从System启动
         android.ddm.DdmHandleAppName.setAppName("system_process",
                 UserHandle.myUserId());
         try {
             //创建Instrumentation,AppContext,Application
             mInstrumentation = new Instrumentation();
             ContextImpl context = ContextImpl.createAppContext(
                     this, getSystemContext().mPackageInfo);
             mInitialApplication = context.mPackageInfo.makeApplication(true, null);
             mInitialApplication.onCreate();
         } catch (Exception e) {
             throw new RuntimeException(
                     "Unable to instantiate Application():" + e.toString(), e);
         }
     }

    //注册Configuration变化的回调通知 
     ViewRootImpl.ConfigChangedCallback configChangedCallback
             = (Configuration globalConfig) -> {
              //当系统配置发生变化时(例如系统语言发生变化),回调该接口,通知资源改变
         synchronized (mResourcesManager) {
             if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig,
                     null /* compat */)) {
                 updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
                         mResourcesManager.getConfiguration().getLocales());

                 if (mPendingConfiguration == null
                         || mPendingConfiguration.isOtherSeqNewer(globalConfig)) {
                     mPendingConfiguration = globalConfig;
                     sendMessage(H.CONFIGURATION_CHANGED, globalConfig);
                 }
             }
         }
     };
     ViewRootImpl.addConfigCallback(configChangedCallback);
 }

看完了ActivityThread.systemMain()方法,我们再来看看getSystemContext()方法

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

它其实是通过调用ContextImpl的createSystemContext方法,在进步看看Context的具体创建过程

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());
    context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
            context.mResourcesManager.getDisplayMetrics());
    return context;
}

可以看到ContextImpl是通过LoadedApk和当前的mainThread创建的SystemContext,此时的LoadedApk还只是个空壳,当PKMS启动后,完成对应的解析,AMS会重新设置这个LoadedApk,至此,过程4中的创建系统上下文已经看完了,我们接着看看过程6中的startBootstrapServices方法

private void startBootstrapServices() {
    ……
    //启动Installer
    Installer installer = mSystemServiceManager.startService(Installer.class);
    //启动DeviceIdentifiersPolicyService
    mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
    //启动mActivityManagerService 
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    //启动PowerManagerService
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

    mActivityManagerService.initPowerManagement();

    // Bring up recovery system in case a rescue party needs a reboot
    if (!SystemProperties.getBoolean("config.disable_noncore", false)) {e");
        mSystemServiceManager.startService(RecoverySystemService.class);
    }

    // Now that we have the bare essentials of the OS up and running, take
    // note that we just booted, which might send out a rescue party if
    // we're stuck in a runtime restart loop.
    RescueParty.noteBoot(mSystemContext);

    // Manages LEDs and display backlight so we need it to bring up the display.
    
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值