Android AMS源码分析阅读(二)

AMS和客户进程间的交互之Application的创建过程

Android应用程序的启动入口在ActivityThread的main()函数,在main()函数中创建了ActivityThread的实例对象,并且调用它的attach()去执行应用程序的启动流程,attach()中的工作就是调用ApplicationThread的attachApplication()去创建application,那么就来看看其中具体的过程:

整个过程大致如图:
在这里插入图片描述

attachApplication过程

当应用程序启动后,就会报告给AMS,自己已经启动完毕可以启动activity了,这个实际上是通过IPC调用AMS的attachApplication()方法完成的,该方法具体如下:

public final void attachApplication(IApplicationThread thread, long startSeq) {
       synchronized (this) {
          //1.获取客户进程pid、uid等相关信息
           int callingPid = Binder.getCallingPid();  
           final int callingUid = Binder.getCallingUid();
           final long origId = Binder.clearCallingIdentity();
           //2.将以上参数传入下面的attachApplicationLocked()方法中
           attachApplicationLocked(thread, callingPid, callingUid, startSeq);
           Binder.restoreCallingIdentity(origId);
       }
   }

再来看看具体的attachApplicationLocked()过程;

 private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid, int callingUid, long startSeq) {

        //1.根据客户端进程pid找到ProcessRecord
        ProcessRecord app;
        long startTime = SystemClock.uptimeMillis();
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);
            }
        } else {
            app = null;
        }
        
        if (app == null && startSeq > 0) {
            final ProcessRecord pending = mPendingStarts.get(startSeq);
            if (pending != null && pending.startUid == callingUid
                    && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
                            startSeq, true)) {
                app = pending;
            }
        }

  		/**
  		  * 2.如果上面找不到对应的processRecord对象,那么说明该pid客户进程是一个没有经过AMS
  		  * 允许的“野进程”,因为AMS在启动任何客户端进程前,都已经在内部为未来的进程创建相应的
  		  * ProcessRecord对象,并且在调用Process.startProcess()返回时,将客户进程的pid
  		  * 赋值到了app.pid变量,如果找不到的话,说明它肯定是一个“野进程”。那么就kill了该进
  		  * 程。
  		  **/
        if (app == null) {
          
            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
            if (pid > 0 && pid != MY_PID) {
                killProcessQuiet(pid);
                //TODO: killProcessGroup(app.info.uid, pid);
            } else {
                try {
                    thread.scheduleExit();
                } catch (Exception e) {
                    // Ignore exceptions.
                }
            }
            return false;
        }

        // If this application record is still attached to a previous
        // process, clean it up now.
        if (app.thread != null) {
            handleAppDiedLocked(app, true, true);
        }

		 /**
		   * 3.给app设置binder的死亡代理
		   **/
		 final String processName = app.processName;
        try {
            AppDeathRecipient adr = new AppDeathRecipient(
                    app, pid, thread);
            thread.asBinder().linkToDeath(adr, 0);
            app.deathRecipient = adr;
        } catch (RemoteException e) {
            app.resetPackageList(mProcessStats);
            startProcessLocked(app, "link fail", processName);
            return false;
        }

        /**
          * 4.给app对象内部的其他相应变量赋值,比如app.thread = thread等。
          **/
        ...

        app.makeActive(thread, mProcessStats);
        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
        app.forcingToImportant = null;
        updateProcessForegroundLocked(app, false, false);
        app.hasShownUi = false;
        app.debugging = false;
        app.cached = false;
        app.killedByAm = false;
        app.killed = false;
		 ....
      
        /**
          * 5.确保目标程序APK文件已经被转换成了odex文件,APK文件实际上是一个zip文件,它在安
          * 装时辉自动在/data/app目录下产生一个dex文件,这个dex文件是从zip文件中提取的,而
          * 为了提高效率,该dex文件在运行前一般都会被系统转换成odex文件,即所谓的Optimized
          *  dex文件,如果检查到还没有生成odex文件,则先要生成odex文件。
          * 
          **/
          
        //设置是否是debug模式   
        try {
            int testMode = ApplicationThreadConstants.DEBUG_OFF;
            if (mDebugApp != null && mDebugApp.equals(processName)) {
                testMode = mWaitForDebugger
                    ? ApplicationThreadConstants.DEBUG_WAIT
                    : ApplicationThreadConstants.DEBUG_ON;
                app.debugging = true;
                if (mDebugTransient) {
                    mDebugApp = mOrigDebugApp;
                    mWaitForDebugger = mOrigWaitForDebugger;
                }
            }

            boolean enableTrackAllocation = false;
            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
                enableTrackAllocation = true;
                mTrackAllocationApp = null;
            }

            ...
            
            
            /**
              * 6.调用thread.bindApplication()方法通知客户进程运行指定的Activity所在的
              * APK文件,这个“指定的activity“被包含在了参数app.info中,这个appinfo来源
              * 于调用者intent从系统中查询到的Applicationinfo信息
              ** /

              
            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
            mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
            if (app.isolatedEntryPoint != null) {
                
                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
            } else if (app.instr != null) {
                thread.bindApplication(.....);
            } else {
                thread.bindApplication(....);
            }
            if (profilerInfo != null) {
                profilerInfo.closeFd();
                profilerInfo = null;
            }
            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
            /**
              * 7.通知完毕后,调用updateLruProcess()更新“最新调用的进程列表”。
              **/
            updateLruProcessLocked(app, false, null);
            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
        } catch (Exception e) {

            app.resetPackageList(mProcessStats);
            app.unlinkDeathRecipient();
            startProcessLocked(app, "bind fail", processName);
            return false;
        }

        // Remove this record from the list of starting applications.
        mPersistentStartingProcesses.remove(app);
  
        mProcessesOnHold.remove(app);

        boolean badApp = false;
        boolean didSomething = false;

     
        if (normalMode) {
            try {
                /** 
                  * 8.通过attachApplicationLock()调用realStartActivityLock()通知客
                  * 户进程运行指定的activity,上一步只是通知目标进程从APK文件中加载
                  * Application类并运行,但是没有真正的启动指定的Activity,而在这一步才
                  * 是真正的启动了目标activity。
                  **/
,                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                  badApp = true;
            }
        }

        /**
          * 8.查询是否有依赖于目标进程的pendingService或者pendingBroadcast服务,如果有
          * 的话,就通知目标进程执行。
          *  
          **/
        if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);
                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
            } catch (Exception e) {
                badApp = true;
            }
        }

  
        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
            try {
                didSomething |= sendPendingBroadcastsLocked(app);
                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
            } catch (Exception e) {
                badApp = true;
            }
        }
		  .....
        return true;
    }

应用进程launch指定的Activity

上面attachApplication()执行完,客户进程已经启动,但是它包含的程序文件只是Framework中的ActivityThread基类,这个过程还没有涉及到应用程序本身的任何文件,这个过程类似于LInux程序的启动过程,即首先由操作系统产生一个空进程,然后再通知它去加载具体的要执行程序文件。

那么现在客户进程(空进程)就要根据AMS提供的ApplicationInfo去加载具体的activity了, 注意了,ApplicationInfo是实现了Parcelable的,所以可以在进程间传递数据。上一步中,客户进程向AMS报告自己已经启动,AMS会执行attachApplication(),在这个方法中调用了ActivityThread.ApplicationThread的bindApplication()方法,ApplicationThread本身是一个Binder对象,看看这个方法的具体实现:

 public final void bindApplication(String processName, ApplicationInfo appInfo....) {

           if (services != null) {
               i...
               // Setup the service cache in the ServiceManager
               ServiceManager.initServiceCache(services);
           }

           setCoreSettings(coreSettings);

   		 //将待启动的程序信息设置给AppBindData,通过handler发送BIND_APPLICATION信息,接下来handler去处理这个信息。
           AppBindData data = new AppBindData();
           data.processName = processName;
           data.appInfo = appInfo;
           data.providers = providers;
           data.instrumentationName = instrumentationName;
           ...
           sendMessage(H.BIND_APPLICATION, data);
       }

ActivityThread的H(即handler)收到了“BIND_APPLICATION”时,则调用handleBindApplication()去处理这个消息,先看一下大致的流程图:

在这里插入图片描述

具体代码如下,这部分代码也是非常长,这里还是选择主干部分代码进行分析:

 private void handleBindApplication(AppBindData data) {
       
   	 ... //获取data信息并且设置给profiler
   	
       Process.setArgV0(data.processName);
       android.ddm.DdmHandleAppName.setAppName(data.processName,
                                               UserHandle.myUserId());
       VMRuntime.setProcessPackageName(data.appInfo.packageName);

       if (mProfiler.profileFd != null) {
           mProfiler.startProfiling();
       }

       ...
       //进行版本判断,指定合适的线程池或者图片解码方式

     
       /**
         * 1. 重设客户进程时区为系统时区,这个是有必要的, 因为系统时区可能在客户进程启动后
         * 改变了,所以需要对进程时区进行重设,否则客户进程有可能不正确。
         **/
       TimeZone.setDefault(null);

      
       /**
         * 重设区域列表,由于所有的应用进程都是从zygote进程复制出来的,zygote本身已经装载
         * 了系统资源,不同的区域代表不同的资源内容,而在zygote装在系统资源时,系统区域是默
         * 认的,而此时用户有可能已经改变了系统区域,
         * 因此需要重新设置区域,当然内部会判断当前区域和默认区域是否一样才决定是否要重新装
         * 载。
   	   **/
       LocaleList.setDefault(data.config.getLocales());

       synchronized (mResourcesManager) {
          
           //因为系统配置是预加载的,如果配置发生了变化就不得知了,所以这里需要更新系统配置。
           mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
           mCurDefaultDisplayDpi = data.config.densityDpi;

           // This calls mResourcesManager so keep it within the synchronized block.
           applyCompatConfiguration(mCurDefaultDisplayDpi);
       }

       data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);

       if (agent != null) {
           handleAttachAgent(agent, data.info);
       }

   	 .....
       //设置像素密度值
       //设置时间格式,12小时制或者24小时制
     

   	 /**
   	   * 2.判断是否是debug模式,那么就show一个debug的弹窗等待用户确认,且允许systrace
   	   *  messages文件,可见其实调试时的"waiting for debugger"对话框其实是应用程序本
   	   *  身的一部分,而不是调试时才会有的。
   	   * 
       if (data.debugMode != ApplicationThreadConstants.DEBUG_OFF) {
           // XXX should have option to change the port.
           Debug.changeDebugPort(8100);
           if (data.debugMode == ApplicationThreadConstants.DEBUG_WAIT) {
               Slog.w(TAG, "Application " + data.info.getPackageName()
                     + " is waiting for the debugger on port 8100...");

               IActivityManager mgr = ActivityManager.getService();
               try {
                   mgr.showWaitingForDebugger(mAppThread, true);
               } catch (RemoteException ex) {
                   throw ex.rethrowFromSystemServer();
               }

               Debug.waitForDebugger();

               try {
                   mgr.showWaitingForDebugger(mAppThread, false);
               } catch (RemoteException ex) {
                   throw ex.rethrowFromSystemServer();
               }

           } else {
               Slog.w(TAG, "Application " + data.info.getPackageName()
                     + " can be debugged on port 8100...");
           }
       }


       boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
       Trace.setAppTracingAllowed(isAppDebuggable);
       ThreadedRenderer.setDebuggingEnabled(isAppDebuggable || Build.IS_DEBUGGABLE);
       if (isAppDebuggable && data.enableBinderTracking) {
           Binder.enableTracing();
       }

       
       //接下来给该客户进程初始化默认的http代理。 
       Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Setup proxies");
       final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
       if (b != null) {
           final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
           try {
               final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
               Proxy.setHttpProxySystemProperty(proxyInfo);
           } catch (RemoteException e) {
               Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
               throw e.rethrowFromSystemServer();
           }
       }
       Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

       // Instrumentation info affects the class loader, so load it before
       // setting up the app context.
       
       /**
         * 3.这一步的工作主要如下:
         * 判断是否应用程序是否存在自定义的Instrumentation,如果存在,则获取类加载器并且加
         * 载Instrumentation类,创建实例mInstrumentation;
         * 如果没有,则使用默认的Instrumentation去创建实例mInstrumentation。
         * 说明:一般情况下应用程序都不会有自定义的Instrumentation类,除非是单元测试
         * (UnitTest)模块,Android提供的这个单元测试框架,允许产生一个专门测试应用程序的
         * 单元测试APK,这个框架正是利用了自定义的Instrumentation类。使得真正的应用程序
         * 在单元测试的“容器”中启动。
         * 
         * 具体如下面代码所示:
         **/
         
         
       final InstrumentationInfo ii;
       
       //首先判断应用程序是否存在data.instrumentationName
       if (data.instrumentationName != null) {
           try {
               ii = new ApplicationPackageManager(null, getPackageManager())
                       .getInstrumentationInfo(data.instrumentationName, 0);
           } catch (PackageManager.NameNotFoundException e) {
               throw new RuntimeException(
                       "Unable to find instrumentation info for: " + data.instrumentationName);
           }
          	.... //检验ABI是否匹配
           }

           mInstrumentationPackageName = ii.packageName;
           mInstrumentationAppDir = ii.sourceDir;
           mInstrumentationSplitAppDirs = ii.splitSourceDirs;
           mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
           mInstrumentedAppDir = data.info.getAppDir();
           mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
           mInstrumentedLibDir = data.info.getLibDir();
       } else {
           ii = null;
       }

   	 //接着创建了Application的Context实例
   	 	   
       final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
      
       .....//这里会创建网络安全配置provider,并且更新LocalList等一些相关信息

       //然后这里根据是否有自定义的Instrumentation来决定用哪种方式生成instrumentation的实例
       if (ii != null) {
           //当存在着自定义的nstrumentation时;
           ApplicationInfo instrApp;
           try {
           	   //从上面的InstrumentationInfo获取ApplicationInfo对象
               instrApp = getPackageManager().getApplicationInfo(ii.packageName, 0,
                       UserHandle.myUserId());
           } catch (RemoteException e) {
               instrApp = null;
           }
           if (instrApp == null) {
               instrApp = new ApplicationInfo();
           }
           ii.copyTo(instrApp);
           instrApp.initForUser(UserHandle.myUserId());
           final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                   appContext.getClassLoader(), false, true, false);
           final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);

           try {
                //获取类加载器
               final ClassLoader cl = instrContext.getClassLoader();
               //加载Instrumentation类并且获取实例mInstrumentation.
               mInstrumentation = (Instrumentation)
                   cl.loadClass(data.instrumentationName.getClassName()).newInstance();
           } catch (Exception e) {
               throw new RuntimeException(
                   "Unable to instantiate instrumentation "
                   + data.instrumentationName + ": " + e.toString(), e);
           }

           final ComponentName component = new ComponentName(ii.packageName, ii.name);
           
           //初始化mInstrumentation的成员变量
           mInstrumentation.init(this, instrContext, appContext, component,
                   data.instrumentationWatcher, data.instrumentationUiAutomationConnection);

          ....
       } else {       
           //当应用程序没有自定义的Instrumentation,那么直接实例化系统默认的就可以了。
           mInstrumentation = new Instrumentation();
           mInstrumentation.basicInit(this);
       }
   		.....

       
       Application app;
       final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
       final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();
       try {
       
           /**
             * 4.调用LoadApk的makeApplication去创建Application的实例,到这里,我们终
             * 于获取到了Application的实例了,同时会创建全局的ApplicationContext对象,
             * 可见,Application是应用程序被加载后运行的第一个类,而且在应用程序中唯一。
             **/
            
           app = data.info.makeApplication(data.restrictedBackupMode, null);

           // Propagate autofill compat state
           app.setAutofillCompatibilityEnabled(data.autofillCompatibilityEnabled);

           mInitialApplication = app;

           /**
             * 5.如果应用程序存在着Provider,那么此刻就可以创建并且启动他们了,可见,
             * provider会先于activity运行,这时activity还没有创建呢。
             **/
           ....
     
           /**
             * 6.此刻,可以通过mInstrumentation去调用Application实例的onCreate()方
             * 法了,对Application进行初始化,并真正的开始运行我们的app程序。
             **/
           try {
               mInstrumentation.onCreate(data.instrumentationArgs);
           }
           catch (Exception e) {
               throw new RuntimeException(
                   "Exception thrown in onCreate() of "
                   + data.instrumentationName + ": " + e.toString(), e);
           }
           try {
               mInstrumentation.callApplicationOnCreate(app);
           } catch (Exception e) {
               if (!mInstrumentation.onException(app, e)) {
                   throw new RuntimeException(
                     "Unable to create application " + app.getClass().getName()
                     + ": " + e.toString(), e);
               }
           }
       } finally {
           // If the app targets < O-MR1, or doesn't change the thread policy
           // during startup, clobber the policy to maintain behavior of b/36951662
           if (data.appInfo.targetSdkVersion < Build.VERSION_CODES.O_MR1
                   || StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) {
               StrictMode.setThreadPolicy(savedPolicy);
           }
       }
   	.....
   }

加载Activity的过程

上面完成了创建Application的工作,接下来,就会调用handleLaunchActivity()来加载指定的activity并且运行,具体代码如下:


 public Activity handleLaunchActivity(ActivityClientRecord r,
           PendingTransactionActions pendingActions, Intent customIntent) {
       
       /**
         * 1.暂停背景运行的内存回收器,该回收器实际上是一个Handler对象,该对象会在系统空闲
         * 时接收回收信息,并执行相应的回收函数。
         **/
       unscheduleGcIdler();
       mSomeActivitiesChanged = true;

       if (r.profilerInfo != null) {
           mProfiler.setProfiler(r.profilerInfo);
           mProfiler.startProfiling();
       }

       // Make sure we are running with the most recent config.
       handleConfigurationChanged(null, null);


       // Initialize before creating the activity
       if (!ThreadedRenderer.sRendererDisabled) {
           GraphicsEnvironment.earlyInitEGL();
       }
       //初始化WMS对象,它也是在Android中交互非常重要的一个对象。
      
       WindowManagerGlobal.initialize();

   	/**
   	  * 2.调用performLaunchActivity()去加载Activity,也就是说,加载Activity的过程
   	  * 移到了这个方法下面。
   	  **/
       final Activity a = performLaunchActivity(r, customIntent);

       if (a != null) {
           r.createdConfig = new Configuration(mConfiguration);
           reportSizeConfigurations(r);
           if (!r.activity.mFinished && pendingActions != null) {
               pendingActions.setOldState(r.state);
               pendingActions.setRestoreInstanceState(true);
               pendingActions.setCallOnPostCreate(true);
           }
       } else {
           // If there was an error, for any reason, tell the activity manager to stop us.
           try {
               ActivityManager.getService()
                       .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                               Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
           } catch (RemoteException ex) {
               throw ex.rethrowFromSystemServer();
           }
       }

       return a;
   }
   

接下来具体看看activity是如何加载的;

   private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
       ActivityInfo aInfo = r.activityInfo;
       if (r.packageInfo == null) {
           r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                   Context.CONTEXT_INCLUDE_CODE);
       }
   	/**
   	  * 1.根据传入参数生成一个ComponentName对象,它是application四大组件(Activity、
   	  * Service、BroadcastReceiver、ContentProvider)的标识符,主要包含两个信息:包
   	  * 名和该组件的类名
   	  **/
       ComponentName component = r.intent.getComponent();
       if (component == null) {
           component = r.intent.resolveActivity(
               mInitialApplication.getPackageManager());
           r.intent.setComponent(component);
       }

       if (r.activityInfo.targetActivity != null) {
           component = new ComponentName(r.activityInfo.packageName,
                   r.activityInfo.targetActivity);
       }
   	 /**
   	   * 2.创建Activity所需的context对象,每一个Activity都包含一个Context对象,
   	   **/
       ContextImpl appContext = createBaseContextForActivity(r);
       
       //3.通过类加载器去生成目标activity的实例对象
       Activity activity = null;
       try {
           java.lang.ClassLoader cl = appContext.getClassLoader();
           activity = mInstrumentation.newActivity(
                   cl, component.getClassName(), r.intent);
           StrictMode.incrementExpectedActivityCount(activity.getClass());
           r.intent.setExtrasClassLoader(cl);
           r.intent.prepareToEnterProcess();
           if (r.state != null) {
               r.state.setClassLoader(cl);
           }
       } catch (Exception e) {
           if (!mInstrumentation.onException(activity, e)) {
               throw new RuntimeException(
                   "Unable to instantiate activity " + component
                   + ": " + e.toString(), e);
           }
       }

       try {
       
       	  //4.获取已经创建好的Application 对象  
          Application app = r.packageInfo.makeApplication(false, mInstrumentation);

           if (activity != null) {
               CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
               Configuration config = new Configuration(mCompatConfiguration);
               if (r.overrideConfig != null) {
                   config.updateFrom(r.overrideConfig);
               }
               
               Window window = null;
               if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                   window = r.mPendingRemoveWindow;
                   r.mPendingRemoveWindow = null;
                   r.mPendingRemoveWindowManager = null;
               }
               appContext.setOuterContext(activity);
               
               /**
                 * 5.调用Activity的attach()方法将context对象赋给Activity 的mBase,
                 * 同时实例化PhoneWindow,设置各类监听,给各种成员变量例如mToken、
                 * mApplication、mUiThread等进行赋值
                 **/
               activity.attach(appContext, this, getInstrumentation(), r.token,
                       r.ident, app, r.intent, r.activityInfo, title, r.parent,
                       r.embeddedID, r.lastNonConfigurationInstances, config,
                       r.referrer, r.voiceInteractor, window, r.configCallback);

               if (customIntent != null) {
                   activity.mIntent = customIntent;
               }
               r.lastNonConfigurationInstances = null;
               checkAndBlockForNetworkAccess();
               activity.mStartedActivity = false;
               int theme = r.activityInfo.getThemeResource();
               
               /**
                 * 6.从AndroidManifest.xml中定义的theme中获取主题模式,如果没有的则使
                 * 用默认的主题模式,再调用setTheme()设置给Activity
                 **/
               if (theme != 0) {
                   activity.setTheme(theme);
               }
   			  
               activity.mCalled = false;
               
                /** 
                  * 7. 判断是否是Persistable模式(5.0之后的一种更强的保存数据模式,例如
                  * power off时)然后这里,终于开始回调Activity的onCreate()生命周期
                  * 了;同时activity中也会调用fragment的生命周期。
                  **/
               if (r.isPersistable()) {
                   mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
               } else {
                   mInstrumentation.callActivityOnCreate(activity, r.state);
               }
               if (!activity.mCalled) {
                   throw new SuperNotCalledException(
                       "Activity " + r.intent.getComponent().toShortString() +
                       " did not call through to super.onCreate()");
               }
               r.activity = activity;
           }
           r.setState(ON_CREATE);

   		  /**
   		    * 8.这里要将当前启动的Activity放入 Activity Thread的mActivities存储,注
   		    * 意了,保存的对象是ActivityClientRecord,而不是直接的Activity。
   		    **/
           mActivities.put(r.token, r);

       } catch (SuperNotCalledException e) {
           throw e;

       } catch (Exception e) {
           if (!mInstrumentation.onException(activity, e)) {
               throw new RuntimeException(
                   "Unable to start activity " + component
                   + ": " + e.toString(), e);
           }
       }

       return activity;
   }

上面的performLaunchActivity()方法返回之后,继续执行handleResumeActivity(),那么再来看看这个方法内部是如何回调activity的onResume()生命周期的;

Activity的resume()过程

public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
           String reason) {
       
        ...
        
        /**
          * 1.内部调用了performResumeActivity(),这个方法内部就是改变activity的生命周
          * 期状态,并且调用activity的onResume()方法,并改变了ActivityRecord的一些
          * pause、stopped的状态变量
          **/
       final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
       if (r == null) {
           // We didn't actually resume the activity, so skipping any follow-up actions.
           return;
       }

       final Activity a = r.activity;

       ....
       
       /**
         * 2. 尽管前面所有的步骤中,创建了Application、Activity、并且调用了Activity的
         * onCreate()、onResume()方法,但是都还没有通知到WMS,没有完成真正的显示工作,
         *  这一步就会去获取activity的window对象,且添加给WMS。
         **/
       if (r.window == null && !a.mFinished && willBeVisible) {
           r.window = r.activity.getWindow();
           View decor = r.window.getDecorView();
           decor.setVisibility(View.INVISIBLE);
           ViewManager wm = a.getWindowManager();
           WindowManager.LayoutParams l = r.window.getAttributes();
           a.mDecor = decor;
           l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
           l.softInputMode |= forwardBit;
           if (r.mPreserveWindow) {
               a.mWindowAdded = true;
               r.mPreserveWindow = false;
            
               ViewRootImpl impl = decor.getViewRootImpl();
               if (impl != null) {
                   impl.notifyChildRebuilt();
               }
           }
           if (a.mVisibleFromClient) {
               if (!a.mWindowAdded) {
                   a.mWindowAdded = true;
                   wm.addView(decor, l);   //将Activity的DecorView添加到WMS中
               } else {
                   a.onWindowAttributesChanged(l);
               }
           }

       } else if (!willBeVisible) {
           if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
           r.hideForNow = true;
       }

  
       cleanUpPendingRemoveWindows(r, false /* force */);

     
       if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
           if (r.newConfig != null) {
               performConfigurationChangedForActivity(r, r.newConfig);
              
               r.newConfig = null;
           }
           
           WindowManager.LayoutParams l = r.window.getAttributes();
           if ((l.softInputMode
                   & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
                   != forwardBit) {
               l.softInputMode = (l.softInputMode
                       & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
                       | forwardBit;
               if (r.activity.mVisibleFromClient) {
                   ViewManager wm = a.getWindowManager();
                   View decor = r.window.getDecorView();
                   wm.updateViewLayout(decor, l); //调用ViewManager去更新viewLayout.
               }
           }

           r.activity.mVisibleFromServer = true;
           mNumVisibleActivities++;
           if (r.activity.mVisibleFromClient) {
                 /**
                  * 3.这一步调用activity的makeVisible(),内部其实是将DecorView设成
                  * 可见,到了这一步,用户终于能够看到了Activity的内容了。
                  **/
               r.activity.makeVisible(); 
              
           }
       }

       r.nextIdle = mNewActivities;
       mNewActivities = r;
     
     	  /**
         * 4.添加一个IdleHandler对象,一般情况下,activity执行完上面步骤后,就进入了空闲
         * 状态,所以可以进行内存回收。
         **/
       Looper.myQueue().addIdleHandler(new Idler());  
      
   }

以上就是整个application的创建以及activity的创建和显示过程。

猜你喜欢

转载自blog.csdn.net/qq_26984087/article/details/86601105