• Framework之AMS的启动流程


    一、Instrumentation类 :  该类是一个工具类,ActivityThread接收到AMS的指令创建和调度交互都由它来执行

      ActivityThread的构造方法很简单就是创建了一个ResourcesManager对象,用于管理应用程序中的资源文件

      Application环境与framework-res.apk构成了Android程序的运行环境,通过Context应用程序的大管家,可以调用进程所用到的资源和方法。

      StackSupervisor类是Activity启动和调度的核心类

      ProcessRecord类保存一个进程的相关信息

    二、AMS服务的启动过程

      1.SystemServer.javamain()

       public static void main(String[] args) {

        new SystemServer().run(); }

      2. SystemServer.javarun()

        private void run() {

          ...

          System.loadLibrary("android_servers");//1

          ...

          mSystemServiceManager = new SystemServiceManager(mSystemContext);//2

          LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

           ...

          try {

            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");

             startBootstrapServices();//3   ---------------->引导服务

             startCoreServices();//4        ---------------->核心服务

             startOtherServices();//5       ---------------->其他服务

        } 

      3.SystemServer.javastartBootstrapServices()

       private void startBootstrapServices() {

        // Activity manager runs the show.

        mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService();

        我们知道SystemServiceManager的startService方法最终会返回Lifecycle类型的对象,紧接着又调用了Lifecycle的getService方法,这个方法会返回AMS类型的mService对象

        mActivityManagerService.setSystemProcess();

         ……

        mActivityManagerService.installSystemProviders();

        ……

        mActivityManagerService.systemReady(new Runnable() {

        @Override public void run() {

        Slog.i(TAG, "Making services ready");

         mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY);

        try { mActivityManagerService.startObservingNativeCrashes();

      4.Lifecycle类的介绍

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

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

        public ActivityManagerService getService() {
          return mService;
        }
      }

      5.AMS的构造方法

       public ActivityManagerService(Context systemContext) {

         //获得系统的ActivityThread

         mSystemThread = ActivityThread.currentActivityThread();  

         //创建一个HandlerThread用来处理AMS接收的命令

        mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);

        mHandlerThread.start();

        mHandler = new MainHandler(mHandlerThread.getLooper());

        mUiHandler = new UiHandler();

        //初始化广播的队列

        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;

        //初始化Service相关的容器

        mServices = new ActiveServices(this);

        //初始化Provider相关的Map,里面保存了注册的ContentProvider

        mProviderMap = new ProviderMap(this);

        //初始化并创建data/system/目录

        File dataDir = Environment.getDataDirectory();

        File systemDir = new File(dataDir, "system");

        systemDir.mkdirs();

        ....

       //初始化StackSupervisor,该类是Activity启动和调度的核心类

        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);

        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);

       6.AMS的方法systemReady

        1:在systemReady的时候初始化了deviceIdleController等对象
        2:移除并杀死了那些不该在AMS之前启动的进程
        3:执行了参数传入的回调函数
        4:启动了Launcer界面和SystemUI
        5:启动那些persistent配置为1的进程。

        总结:AMS服务启动主要分为几个步骤  小米视频增加组内自动化测试

        1. 创建了SystemServer进程的运行环境,包括一个ActivityThread主线程,一个和系统进程相关的Context对象。
        2. 调用AMS的构造方法和start方法,对AMS必要的内容进行初始化
        3. 将函数AMS注册到ServiceManager中,同时对systemServer进程也创建了一个ProcessRecord对象,并设置Context的appliation为framework-res的application对象
        4. 将settingsProvider加载到系统进程systemServer中
        5. 调用systemReady方法做一些启动前的就绪工作,并启动了HomeActivity和SystemUI
     
      三、Activity的启动流程
        1.Activity的startActivity()
         public void startActivity(Intent intent, @Nullable Bundle options) {
          if (options != null) {
            startActivityForResult(intent, -1, options); …… }
      
        2.Activity的startActivityForResult()
         public void startActivityForResult( ........) {
          Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, who, intent, requestCode, options);
          …… }
     
        3.Instrumentation的execStartActivity
          public ActivityResult execStartActivity( .......) {
            IApplicationThread whoThread = (IApplicationThread) contextThread;
            try {
              //intent做进程间传输的准备工作
              intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess();
              //进程间传输,最终调用到AMS服务AMS.startActivity
              int result = ActivityManagerNative.getDefault().startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
            checkStartActivityResult(result, intent); } …… }
        
        4.AMS的startActivity
         public final int startActivity(......) {
          return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, options, UserHandle.getCallingUserId()); }
       
        5.AMS的startActivityAsUser
          public final int startActivityAsUser(......) {
            ……
            return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, null, null, options, false, userId, null, null); }
            
          ActivityStackSupervisor是Activity启动和调度的核心类,主要管理Task和Stack
          
        6.ActivityStarter的startActivityMayWait () : 根据Intent从PMS中查询目标Activity的信息
        final int startActivityMayWait(.....){
        //PMS服务根据intent查询要启动的Activity B的信息,保存到ActivityInfo中
        intent = new Intent(intent);
        ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
        ……
        //决定当前活动的stack
        ActivityContainer container = (ActivityContainer)iContainer; 
         //将PMS中查询到的Activity B的信息当做参数
        int res = startActivity(caller, intent, resolvedType, aInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, null, container, inTask);
         
        7.ActivityStarter的startActivity() : 在AMS中找调用进程的processRecord信息,调用Activity的ActivityRecord信息,目标Activity还没有启动,所以需要先创建一个目标Activity的ActivityRecord信息
         final int startActivityLocked(......){
           //即调用者的Activity组件
           ActivityRecord sourceRecord = null;
          //返回结果的Activity组件
           ActivityRecord resultRecord = null;
           if (resultTo != null) {
            //根据resultTo Binder对象得到其指向的ActivityRecord,即Activity A的ActivityRecord信息
            sourceRecord = isInAnyStackLocked(resultTo);
            //一般情况下请求的Activity和要接收返回结果的Activity是同一个
            if (sourceRecord != null) {
            if (requestCode >= 0 && !sourceRecord.finishing) { resultRecord = sourceRecord; } } }
            .......
            //根据准备的信息,创建一个即将启动的ActivityRecord对象,即Activity B
            ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null, this, container, options);
            //将刚创建的目标Activity的ActivityRecord作为参数,继续调用startActivityUncheckedLocked(startActivity)方法来启动
            err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask); (startActivity)
          
            小结 : 该方法主要作用是创建一个即将要启动的Activity的ActivityRecord对象,根据参数传进来的代表Activity A的binder对象,来获得Activity A的ActivityRecord信息。
                 然后获取调用进程的pid和调用程序的uid,根据这些信息和ainfo创建一个ActivityRecord对象r,代表ActivityB。
               这样就获取了调用者的Activity A的组件信息,和即将要启动的目标Activity B的信息。
               分别保存在sourceRecord和r中,最后调用startActivityUncheckedLocked方法来继续启动Activity B
     
        9.ActivityStarter的startActivityUnchecked的函数 : 主要来处理启动模式相关的逻辑,根据不同的启动模式,找到相应的对的Task,然后又相应的Task进行处理
         ........
         setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,voiceInteractor);    处理Activity的四种不同的启动模式 默认为standard模式
         .......
         if (dontStart) {
          if (mDoResume) {
            //make sure we have correctly resumed the top activity  确保当前的activity的栈顶
            mSupervisor.resumeFocusedStackTopActivityLocked();} 
     
        10.ActivityStackSupervisor的resumeFocusedStackTopActivityLocked()
          
        11.ActivityStack的resumeTopActivityInnerLocked()
     
        12.ActivityStackSupervisor的startSpecificActivityLocked()
        
        13.ActivityStackSupervisor的pauseBackStacks(....) :  暂停所有堆栈中的所有活动,或者只暂停后面的堆栈
          someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,dontWait);
          

          ActivityStack有三个成员变量,mResumedActivity表示这个栈中处于激活状态的Activity。这个栈中处于激活状态的Acticity就是Acticity A了。

          mLastPausedActivity表示上一次被暂停的Activity。

          mLastPausingActivity即当前栈中正在被暂停的Activity。

          mResumedActivity表示Activity A不是Null,所以调用startPasingLocked来暂停Activity A   

       Activity启动流程的第一部分就到此为止。总结下这部分做的主要工作

    1. 调用Activity的startActivity方法来启动目标Activity
    2. 调用Instrumentation的方法execStartActivity方法,方便Instrumentation对交互进行监测
    3. 以上部分是在App1的进程中执行,之后会通过进程间通信调用到AMS服务中调用AMS的startActivity方法。此时进入SystemServer进程。
    4. 然后由AMS中管理Acticity核心调度的类ActivityStackSupervisor的方法startActivityMayWait来处理。该方法中主要是根据Intent从PMS中查询目标Activity的信息
    5. ActivityStackSuperVisor的startActivityLocked方法主要是在AMS中找调用进程的processRecord信息,调用Activity的ActivityRecord信息,目标Activity还没有启动,所以需要先创建一个目标Activity的ActivityRecord信息。
    6. ActivityStackSuperVisor的StartActivityUncheckedLocked方法主要来处理启动模式相关的逻辑,根据不同的启动模式,找到相应的对的Task,然后又相应的Task进行处理
    7. ActivityStack将目标Activity加入到对应的Task顶部
    8. 调用ActivityStackSuperVisor的resumeTopActivityLocked方法找到处于前台的Stack,然后调用它的resumeTopActivityLocked方法激活目标Activity.
    9. 当前的Stack的栈开始Pasuing调用的Activity

      

      三、暂停ActivityA的流程

        final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming, boolean dontWait) {

          //mResumeActivity代表当前激活的Activity,即Activity A

          ActivityRecord prev = mResumedActivity;

          ……

          //当前处于激活状态mResumedActivity 的设置为null

          mResumedActivity = null;

          //即将要处于pasuing状态的Activity 就是Activity A

          mPausingActivity = prev;

          mLastPausedActivity = prev;

          ……

          try {
          prev.shortComponentName, "userLeaving=" + userLeaving);
          mService.updateUsageStats(prev, false);
          mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,PauseActivityItem.obtain(prev.finishing, userLeaving,
          prev.configChangeFlags, pauseImmediately));

        2.   AMS的activityPaused

          public final void activityPaused(IBinder token) {

          //获或Activity 所在的ActivityStack

          ActivityStack stack = ActivityRecord.getStackLocked(token);

          if (stack != null) {

          //调用目标ActivityStack的activityPauseLocked方法

          stack.activityPausedLocked(token, false); } }

        3. ActivityStack 的activityPauseLocked

         final void activityPausedLocked(IBinder token, boolean timeout) {

          //根据token获取Activity A的ActivityRecord对象

          final ActivityRecord r = isInStackLocked(token);

          if (r != null) {

          //移除pause超时消息

          mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);

          if (mPausingActivity == r) {

          //调用completePauseLocked方法继续执行pause逻辑

          completePauseLocked(true); } ……

         注解:Token代表的是Activity的binder对象,根据token可以获得Activity A的信息ActivityRecord,移除Pause超时消息,

           当执行完pause逻辑的ActivityRecord和我们执行pause逻辑前的activityRecord一样的时候,即是同一个Activity,

           就可以调用completePauseLocked方法来完成Activity A Pause最后的逻辑了

      
        四、启动一个新的Activity B
            1. ActivityStackSuperVisor 的 startSpecificActivityLocked : 开启一个新的Activity
          void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
          //获取目标Activity的进程ProcessRecord
          ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true);
          ……
          //,由于目标Activity所在进程还没有创建,所以为空
          if (app != null && app.thread != null) {
          …… } 
          mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); }
       
        2. AMS.的startProcessLocked 
          final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, ……) {
         long startTime = SystemClock.elapsedRealtime();
         ProcessRecord app; if (!isolated) {
         app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
         String hostingNameStr = hostingName != null ? hostingName.flattenToShortString() : null;
         ……
         startProcessLocked( app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
     
        3. AMS的startProcessLocked
        private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
                  String seInfo, String requiredAbi, String instructionSet, String invokeWith,long startTime) {
              .....
              final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,requiredAbi, instructionSet, invokeWith, app.startTime);
     
       4. AMS的startProcess
        private ProcessStartResult startProcess(String hostingType, String entryPoint,ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
                            String seInfo, String requiredAbi, String instructionSet, String invokeWith,long startTime) {
        startResult = Process.start(entryPoint,app.processName, uid, uid, gids, runtimeFlags, mountExternal,
              app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, invokeWith,new String[] {PROC_START_SEQ_IDENT + app.startSeq});
      
        方法的注解: 这个方法做的主要工作就是调用Process的静态方法启动一个新的进程,启动新的进程的过程大概是,Zygote进程会fork一个新的子进程出来,子进程创建完成之后,classLoader加载ActivityThread类并创建一个ActivityThread实例,反射调用ActivityThread的main方法。这样ActivityThread主线程就在新的进程中启动起来了。接着看ActivityThread的main方法,此时已经在新的进程中执行了。我们来看ActivityThread的main方法。
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
         

        

  • 相关阅读:
    对虚机设备Bridge ,Vlan, VETH, TAP详细介绍
    DevStack部署Openstack环境
    Ubuntu配置 PPTP 服务器端
    Ubuntu 配置PPTP客户端
    Git学习笔记
    Mysql安装随记,整理内容来源网络
    GitHub访问慢的优化处理
    NetCore部署到Linux服务器+Supervisor的步骤及过程中踩过的坑
    JavaScript的定时器如何先触发一次再延时
    在实现文本框只能输入数字和小数点的基础上实现了价格样式(保留两位小数)
  • 原文地址:https://www.cnblogs.com/liunx1109/p/11124753.html
Copyright © 2020-2023  润新知