在android面试中,咱们常会遇到Framework面试相关问题,而今天要共享的便是Activity发动流程剖析

其首要调查的是程序员对activity 的发动进程,以及发动进程中各大类的联系。

问题正解:

Activity的发动进程一般有两种情况:第一种,activity地点的进程没有创立,那么这个进程就会涉及到App进程的创立,咱们能够在《Android app进程是怎样发动的》的章节去得到具体阐明,在这儿就不赘述了;第二种,App进程存在,那么对应的Activity发动流程将是下面剖析的要点。

下文会剖析整个activity 发动的流程,一同剖析一下它的生命周期的切换进程,最终再剖析一下办理activity的几个类的根本情况。

1.Activity发动流程

平时咱们开发的运用都是展示在Android体系桌面上,这个体系桌面其实也是一个Android运用,它叫Launcher。所以本文经过源码层面从Launcher调用ATMS,ATMS再经过AMS发送socket恳求给zygote,由zygote fork出app进程,然后再经过反射调用ActivityThread 的main函数,开端运转app进程的代码。在ActivityThread main函数中,会履行AMS的 attachApplication办法,将Application的binder赋值给AMS,然后再由AMS经过这个IBinder去调用ApplicationThread的bindApplication函数履行application的生命周期,紧接着AMS再直线ATMS的attachApplication办法,从而发动Activity并履行Activity的相关生命周期。

下文咱们将要点对Activity发动流程进行剖析。(文中源码根据Android 11 )。

1.1 Launcher 调用Activity的进程

在这个阶段,Launcher仅仅一个app,当用户点击Launcher上app icon的时分就会履行Launcher中的代码,在这个流程里边,Launcher首要会经过Instrumentation类跨进程调用ATMS(android 10之前是AMS)的代码去发动Activity,具体的其他细节不是咱们重视的要点,有感爱好的同学能够自行查看源码进行了解。咱们将剖析的要点放到ATMS发动Activity的流程里边来。

每日一题:Activity启动流程分析

从上图,流程图能够看到,ActivityTaskManagerService是经过ActivityStarter来发动Activity,为什么存在ActivityStarter类呢?

1.1.1 ActivityStarter类的阐明

ActivityStarter它是一个用于解释怎么发动一个Activity的操控器,用来装备actiivty的各种了解并加载发动 Activity 的类,此类记载一切逻辑,用于确定怎么将意图和标志转换为Activity以及关联的使命和堆栈。

在ActivityStarter中包含了一个静态内部类Request,这个类或许十分恰当的阐明ActivityStarter的作用。它的部分代码如下:

static class Request {
   ...
    IApplicationThread caller;
    Intent intent;
    NeededUriGrants intentGrants;
    // A copy of the original requested intent, in case for ephemeral app launch.
    Intent ephemeralIntent;
    String resolvedType;
    ActivityInfo activityInfo;
    ResolveInfo resolveInfo;
    IVoiceInteractionSession voiceSession;
    IVoiceInteractor voiceInteractor;
    IBinder resultTo;
    String resultWho;
    int requestCode;
    int callingPid = DEFAULT_CALLING_PID;
    int callingUid = DEFAULT_CALLING_UID;
    String callingPackage;
    @Nullable String callingFeatureId;
    int realCallingPid = DEFAULT_REAL_CALLING_PID;
    int realCallingUid = DEFAULT_REAL_CALLING_UID;
    int startFlags;
    SafeActivityOptions activityOptions;
    boolean ignoreTargetSecurity;
    boolean componentSpecified;
    boolean avoidMoveToFront;
    ActivityRecord[] outActivity;
    Task inTask;
    String reason;
    ProfilerInfo profilerInfo;
    Configuration globalConfig;
    int userId;
    WaitResult waitResult;
    int filterCallingUid;
    PendingIntentRecord originatingPendingIntent;
    boolean allowBackgroundActivityStart;
   ...
}

上面的代码咱们不能发现,这个类里边有十分多的参数,而这些参数就包含了发动activity的相关信息和被发动Activity的相关信息。咱们不难知道,在发动activity之前把一切信息都预备全,这个作业就需求交给ActivityStarter类来做。别的,ActivityA发动ActivityB时,代码是这样的:startActivity(new Intent(ActivityA.this,ActivityB.class)),参数信息只要三个Intent,context和ActivityB.class,这些信息就会在ActivtyStarter类中被封装成为一个request,有了这些信息,才能去进行发动的下一步作业。

咱们一同来看一下图29-1中的step 4 executeRequest的代码:

private int executeRequest(Request request) {
    ActivityInfo aInfo = request.activityInfo;
    ResolveInfo rInfo = request.resolveInfo;
    String resultWho = request.resultWho;
    Task inTask = request.inTask;
    
    ActivityRecord sourceRecord = null;//code 1
    ActivityRecord resultRecord = null;//code 2
    
    if (resultTo != null) {
      sourceRecord = mRootWindowContainer.isInAnyStack(resultTo); //code 3
       ......
      if (sourceRecord != null) {
        if (requestCode >= 0 && !sourceRecord.finishing) {
          resultRecord = sourceRecord;
         }
       }
     }
     ......
    //code 4
    final ActivityRecord r = new ActivityRecord(mService,callerApp, callingPid, 
           callingUid, callingPackage, callingFeatureId, intent, resolvedType, 
        aInfo,mService.getGlobalConfiguration(), resultRecord, resultWho, 
        requestCode,request.componentSpecified, voiceSession != null, 
        mSupervisor, checkedOptions, sourceRecord);
    //code 5
    mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
        request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
        inTask,restrictedBgActivity, intentGrants);
}

1)上面代码中code 1 &code 2 界说了两个ActivityRecord;

2)code3处初始化sourceRecord,这个sourceRecord,便是构建了当时发动Activity的activity在AMS中的ActivtyRecord。比方ActivityA发动ActivityB,那么这个ActivityRecord便是ActivityA 在AMS中的存在形式。当然这也便是说要在发动新Activity之前要知道sourceReord是谁。

3)code4 new了一个ActivityRecord,它便是要被发动的Activity。

4)code5 调了startActivityUnchecked()办法,履行下一步的生命周期流程的调度。

1.1.2 ActivityStartController类

这个类相对较简略,看名字知道它是一个ActivityStart的操控器,这个类首要是接纳Activity发动的各种恳求,并将这些恳求封装成为一个能够被ActivityStarter处理的活动。所以,ActivityStarter方针的产生,是由ActivityStartController供给的。一同,它还会负责处理环绕活动发动流程开端的环节的逻辑,如图29-1中的第5步,当app中有一系列的activity处于pending需求发动的时分,这个时分就会调用doPendingActivityLaunches办法,处理一切的pending的activity。

void doPendingActivityLaunches(boolean doResume) {
  //循环获取一切的pending情况的Activity,并履行发动逻辑
    while (!mPendingActivityLaunches.isEmpty()) {
        final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
        final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
        final ActivityStarter starter = obtainStarter(null /* intent */,
                "pendingActivityLaunch");
        try {
            starter.startResolvedActivity(pal.r, pal.sourceRecord, null, null, 
            pal.startFlags, resume, pal.r.pendingOptions, null, pal.intentGrants);
        } catch (Exception e) {
            Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
            pal.sendErrorResult(e.getMessage());
        }
    }
}
​

经过上面的代码,咱们不难发现在图29-1中的第5步,所走的代码,其实便是将一切要发动而没有发动的Activity们进行共同的发动办理,仅仅真实发动的进程依旧交由AcitivityStarter的startResolvedActivity去完结。

1.1.3 发动期间的黑白屏现象

在app发动的时分,在AcitivityStarter发动activity的时分会有一个特殊的进程,这个进程便是发动一个黑白屏,用于提醒用户,正在发动新的app。那么这个发动黑白屏的进程是怎样的的呢?

咱们一同来看一下图29-1中的第8步的代码startActivityInner。

int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, Task inTask,
        boolean restrictedBgActivity, NeededUriGrants intentGrants) {
    //初始化装备,mStartActivity、mLaunchMode等
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
            voiceInteractor, restrictedBgActivity);
​
     // 核算要发动的Activity的task标志,也便是核算发动形式
    computeLaunchingTaskFlags();
    computeSourceStack();
​
    //将mLaunchFlags设置给Intent,也便是设置发动形式
    mIntent.setFlags(mLaunchFlags);
​
    final Task reusedTask = getReusableTask();
​
    ......
    // Compute if there is an existing task that should be used for.
    final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
    final boolean newTask = targetTask == null;
    mTargetTask = targetTask;
​
    computeLaunchParams(r, sourceRecord, targetTask);
​
    ...
​
  // code1
    // 创立发动黑白屏window
    mTargetStack.startActivityLocked(mStartActivity,
            topStack != null ? topStack.getTopNonFinishingActivity() : null, newTask,
            mKeepCurTransition, mOptions);
    if (mDoResume) {
        final ActivityRecord topTaskActivity =
                mStartActivity.getTask().topRunningActivityLocked();
        if (!mTargetStack.isTopActivityFocusable()
                || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
                && mStartActivity != topTaskActivity)) {
            mTargetStack.ensureActivitiesVisible(null /* starting */,
                    0 /* configChanges */, !PRESERVE_WINDOWS);
            mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
        } else {
            if (mTargetStack.isTopActivityFocusable()
                    && !mRootWindowContainer.isTopDisplayFocusedStack(mTargetStack)) {
                mTargetStack.moveToFront("startActivityInner");
            }
            //code2 将发动流程交给RootWindowContainer去履行,并经过
            mRootWindowContainer.resumeFocusedStacksTopActivities(
                    mTargetStack, mStartActivity, mOptions);
        }
    }
    ......
​
    return START_SUCCESS;
}

函数一开端先初始化发动activity需求的装备,然后再根据装备参数核算出发动形式,并将发动形式设置给Intent作为后期备用的变量。接着会运转到code1,此刻便是创立一个黑白屏。在剖析黑白屏创立办法前,咱们先剖析一下黑白屏为什么在Activity进程创立之前会发动?

当用户点击Launcher界面app icon的时分,为了让点击者在第一时间能够感受到点击的呼应,此刻有必要要有界面切换来证明改动的存在。在app发动流程中,假如在app进程创立后才显现这个黑白屏,那么Launcher界面将出现一个比较长的等待时间,这将会被用户错误的认知为点击没有及时呼应。因而,在app进程还没有创立的时分,在发动activity的进程中,一旦设置了activity的发动形式就马上创立一个黑白屏,用于联接点击app icon到app真实显现这中心的时间空隙,这也是在activity发动进程中的一个巧妙规划。关于黑白屏的具体显现流程,感爱好的朋友能够去阅览其他相关章节补充学习。

1.1.4 RootWindowContainer类的阐明

Android10新增的类,当activity发动的时分,会将整个发动流程转交给RootWindowContainer去履行,为什么会这样去做了?咱们接下来剖析。

RootWindowContainer是窗口容器(WindowContainer)的根容器,办理了一切窗口容器,设备上一切的窗口(Window)、显现(Display)都是由它来办理的。resumeFocusedStacksTopActivities函数会恢复对应使命栈顶部的Activity。这个办法会查看一些可见性相关的特点,假如当时需求resume的activityStack 是可见的,这个时分才resume,而可见性是由RootWindowContainer中的窗口操控的。所以,每个activity都有自己的窗口,为了操控activity窗口的可见性,Activity的发动有必要经过RootWindowContainer。

1.1.5 小结

从图29-1能够看出,Activity的发动会有一个相对绵长的前期预备阶段,这个阶段所做的事情如下:

1)ATMS发出发动activity的恳求;

2)将发动Activity的动作所需求预备的参数全部封装成为ActivityStarter里边的参数,也便是说ActivityStarter存储了一个activity发动所需求的一切的参数;

3)因为或许存在一次发动多个Activity的情况,或许积累了多个activity需求发动的情况,所以此刻需求将一切能够发动的activity进行发动,因而发动流程需求去走到ActivityStarterController里边进行处理;

4)当真实发动Activity的时分,假如是发动的application的launcher activity,那么咱们需求先供给一个黑白屏,因为在用户点击发动application的时分,用户需求对发动App这个动作有感知,但是此刻App发动或许比较缓慢没办法马上显现,因而就需求先创立一个黑白屏。

5)因为发动activity会改动activity的窗口的可见性,而这个可见性的办理是由RootWindowContainer进行,因而在发动路上需求经过这个类来进行可见性操控的办理。

接下来,咱们继续剖析Activity的发动流程

1.2 Activity发动流程在AMS中的履行

每日一题:Activity启动流程分析

图29-2

1.2.1 ActivityRecord,Task,ActivityStack,ActivityStackSupervisor类阐明

咱们要了解Activity发动流程,首先是要了解一些要害类的信息。

ActivityRecord:一个ActivityRecord对应着一个Activity,保存着一个Activity的一切信息;但是一个Activity或许会有多个ActivityRecord,因为Activity或许会被发动屡次,首要是取决于Activity的发动形式。

Task:Android体系中的每个Activity都坐落一个Task中。一个Task能够包含多个Activity,同一个Activity也或许有多个实例。 在AndroidManifest.xml中,咱们能够经过 android:launchMode 来操控Activity在Task中的实例。Task办理的意义还在于近期使命列表以及Back栈。 当你经过多使命键(有些设备上是长按Home键。有些设备上是专门供给的多使命键)调出多使命时,事实上便是从ActivityManagerService获取了近期发动的Task列表。

ActivityStack:Task是它的父类,是一个办理类,办理着一切Activity,内部保护了Activity的一切情况、特殊情况的Actvity和Activity以及相关的列表数据。

ActivityStackSupervisorActivityStack是由ActivityStackSupervisor来进行办理,而这个是在ATMS的initialize中被创立出来的。ATMS初始化的时分,会创立一个ActivityStackSupervisor方针用于共同办理一些业务:1)将显现层次结构相关的内容移动到RootWindowContainer中;2)将与activity生命周期相关的业务的处理转交给ActivityLifeCyler处理;3)处理点击物理按键Menu键后使命栈的处理。

注意:在Android 11版本中上面的类的划分已经和之前的版本进行了十分大的修改,所以责任也各不相同,编者注意到在Android12版本中,已经去掉了ActivityStack类和ActivityStackSupervisor类,代替他们的是Task类和ActivityTaskSupervisor类,感爱好的读者能够拿源码进行阅览。

小结: 在AMS发动的时分,会创立一个ActivityStackSupervisor方针,ActivityStackSupervisor创立和办理Android体系中一切运用的ActivityStack,一个ActivityStack对应和包含一个运用中一切的栈。

有了以上对类的根本了解,咱们就很简单了解图29-2的流程了。

一个app一切的Activity都会被ActivityStack进行办理,因而发动Activity自然也是在ActivityStack中进行,所以在完结发动流程的前9步预备作业后,自然就在第10步迈入了ActivityStack中。ActivityStack开端真实的发动Activity的时分,需求先履行12步,第12步会先让当时正在显现的Activity履行它的pause生命周期,然后再去履行13步:预备发动指定的Activity。

咱们能够看一下ActivityStack中下面的核心代码

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    ...
    // 停止当时的Activity
    if (mResumedActivity != null) {
        if (DEBUG_STATES) Slog.d(TAG_STATES,
                "resumeTopActivityLocked: Pausing " + mResumedActivity);
        // 停止当时的Activity
        pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next);//code1
    }
    ...
    if (next.attachedToProcess()){
    ...
    } else {
        ...
        //发动指定的Activity
        mStackSupervisor.startSpecificActivity(next, true, true); //code2
    }
​
    return true;
}

经过上面的code1,此处代码是用于pause 当时activity的代码,code2 则是发动特定Activity的代码。

关于startPausingLocked() 办法去触发当时Activity履行pause生命周期的具体流程,咱们就不做体系剖析了,大致流程会和履行activity onCreate的流程共同,感爱好的读者能够自行阅览源码。咱们将要点放到Activity发动上面来,所以请咱们看下面的ClientTransaction传递流程。

1.3 Activity发动中事情的跨进程通信

每日一题:Activity启动流程分析

图 29-4

从Android 8之后,activity的发动流程就加入了触发器的机制,这个机制出现的目的是为了更加友爱的办理activity的生命周期,但是,本人感觉它更让人费解了。不管怎样,咱们一同剖析一下它的流程和类的联系,用于帮助咱们了解这个流程。

ClientLifecycleManager 是办理 Activity 生命周期的,在 ActivityTaskManagerService 里边供给 getLifecycleManager 来获取此方针,其间 mLifecycleManager 是在 ActivityTaskManagerService 的构造办法里边初始化的。

public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
   ......
  private final ClientLifecycleManager mLifecycleManager;
   ......
  public ActivityTaskManagerService(Context context) {
    mContext = context;
    mFactoryTest = FactoryTest.getMode();
    mSystemThread = ActivityThread.currentActivityThread();
    mUiContext = mSystemThread.getSystemUiContext();
    mLifecycleManager = new ClientLifecycleManager();//mLifecycleManager初始化
    mInternal = new LocalService();
     ......
   }
   ......
  //获取mLifecycleManager方针
  ClientLifecycleManager getLifecycleManager() {
    return mLifecycleManager;
   }
   ......
}

相关类功用阐明:

ClientTransactionItem 方针,一个回调音讯,client 端能够调用履行,实现了 BaseClientRequest 接口,在接口里边界说了3个办法:preExecute,execute,poseExecute。

ClientTransaction 是一个容器,持有一系列能够发送给 client 的音讯(比方声明周期的情况),包含有 mActivityCallbacks 列表和一个方针情况 mLifecycleStateRequest。

TransactionExecutor 用来履行 ClientTransaction,以正确的顺序办理业务履行 execute(),界说在 ActivityThread 运用端。

ClientTransactionHandler是一个抽象类,界说了一系列生命周期处理Activity生命周期的接口,由ActivityThread实现。

别的,有一个类也在这儿和咱们一同介绍一下:

ActivityLifecycleItem 承继自 ClientTransctionItem,首要的子类有 ResumeActivityItem、PauseActivityItem、StopActivityItem、DestoryActivityItem。

ActivityThread 它办理运用程序进程中主线程中履行的调度和履行活动、广播以及活动办理器恳求的其他操作。

小结

图29-4展示的代码履行流程能够知道,第15步,生命周期的履行是ActivityStackSupervisor这个activity栈的大管家拿着在ATMS中所创立的ClientLifecycleManager去履行生命周期的触发器。而生命周期的处理有必要要经过生命周期事物存储的容器来分发,也便是第16步走ClientTransaction。但是Activity生命周期的履行到现在停止仍是在SystemServer进程也便是在AMS地点的进程中,终究Activity的生命周期的履行还有必要是在App进程中,所以就有了第17步,经过binder调用将生命周期的履行分发给Activity地点的进程去履行。当IApplicationThread 收到AMS地点进程发送过来的生命周期处理音讯的时分,开端发送一个handler事情来处理这个生命周期,这便是第18步的履行。最终,app进程会去履行生命周期的触发器来处理ClientTransation事情。

请咱们要点重视一个细节,也便是第17步,进程间完结了一次从systemServer进程到Activity地点的app进程进行切换的进程。

1.4 运用进程中生命周期的履行流程

生命周期的履行到现在这一步算是一个重要的分水岭,因为接下来的履行进程全部是在App进程中进行,接下来的履行流程咱们能够看一下下面的流程图。

每日一题:Activity启动流程分析
图 29-5

在履行发动流程中,咱们先来看第14步ActivityStackSupervisor中的realStartActivityLocked函数一段核心代码:

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {
​
    ......
    // Create activity launch transaction.
    // 创立 clientTransaction 方针
    final ClientTransaction clientTransaction = ClientTransaction.obtain(
            proc.getThread(), r.appToken);
​
    final DisplayContent dc = r.getDisplay().mDisplayContent;
    //code1
    // 增加LaunchActivityItem
    clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
            System.identityHashCode(r), r.info,
            // TODO: Have this take the merged configuration instead of separate global
            // and override configs.
            mergedConfiguration.getGlobalConfiguration(),
            mergedConfiguration.getOverrideConfiguration(), r.compat,
            r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
            r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
            dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
            r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));
​
    // Set desired final state.
    final ActivityLifecycleItem lifecycleItem;
    if (andResume) {
        //需求Rusume的话,设置ResumeActivityItem到clientTransaction中
        lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
    } else {
        lifecycleItem = PauseActivityItem.obtain();
    }
  //code 2
    clientTransaction.setLifecycleStateRequest(lifecycleItem);
​
    // code3
    // Schedule transaction.
    // 获取生命周期办理类 ClientLifecycleManager,并履行业务
    mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    ......
    return true;
}

以上代码创立了一个clientTransaction方针,并设置了clientTransaction方针的各参数。从上面的代码code1,咱们构建了一个LaunchActivityItem,并且将它增加到了clientTransaction的Callback列表中;然后在code2中往clientTransaction中设置了当时阶段终究想要履行的生命周期情况,也便是到生命周期的resume情况,所以再code2 代码处向clientTransation中设置了LifecycleStateRequest,也便是本次transaction希望履行的activity的生命周期的终究的情况,也便是增加了ResumeActivityItem,终究情况是activity的resume;最终在code3 把这个封装的clientTransaction 传递给了ClientLifecycleManager,这个clientTransaction方针被第17步的跨进程通信传给了app进程,所以接下来生命周期的履行就会依照AMS中构建的生命周期办理主意开端履行,也便是会依照图29-5的流程开端履行。

在Activity发动流程履行到TransactionExecutor中的excute的时分,此刻的代码已经履行到了app进程里边了。咱们一同来看一下第19步execute函数的履行流程,流程中咱们只展示核心代码:

public void execute(ClientTransaction transaction) {
    ......
​
    executeCallbacks(transaction); //code1executeLifecycleState(transaction); //code2
    mPendingActions.clear();
    if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}

在第19步,也便是在履行上面的excute函数的时分,会履行两个十分重要的代码:code1&code2,code1便是咱们流程图中的第20步,而code2 便是咱们流程图中的第24步。咱们一同来剖析一下这两个流程:

1.4.1 履行executeCallbacks函数

code1所引发的第20步,这个进程是履行在14步ActivityStackSupervisor中的realStartActivityLocked里边增加的Callback的这个阶段,咱们经过上面代码的剖析能够得到一个定论,这次从第20步履行到第23步,整个流程是环绕当时Activity的launch流程进行。当咱们阅览第22步handleLaunchActivity源码的时分,不难发现,在代码履行中会履行Activity的创立以及attach的生命周期函数,然后再履行onCreate生命周期,具体的代码如下:

ActivityThread.java
​
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
    ......
    WindowManagerGlobal.initialize(); //code1
​
​
    final Activity a = performLaunchActivity(r, customIntent); //code2
​
    ......
}
​
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ......
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
        //创立一个activity
        activity = mInstrumentation.newActivity( //code 3
                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 {
        //LoadedApk 构建 makeApplication 
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
​
        ......
​
        if (activity != null) {
            ......
​
            // Activity resources must be initialized with the same loaders as the
            // application context.
            appContext.getResources().addLoaders(
                    app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
​
            appContext.setOuterContext(activity);
            //code4
            //会在这个办法中创立Activity的PhoneWindow,并绑定对应的WindowManager。
            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,
                    r.assistToken);
​
            if (customIntent != null) {
                activity.mIntent = customIntent;
            }
            r.lastNonConfigurationInstances = null;
            checkAndBlockForNetworkAccess();
            activity.mStartedActivity = false;
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
                activity.setTheme(theme);
            }
​
            activity.mCalled = false;
            //code5
            // 设置 mLifecycleState 为 ON_CREATE
            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;
            mLastReportedWindowingMode.put(activity.getActivityToken(),
                    config.windowConfiguration.getWindowingMode());
        }
        // 设置 mLifecycleState 为 ON_CREATE
        r.setState(ON_CREATE);
​
        // updatePendingActivityConfiguration() reads from mActivities to update
        // ActivityClientRecord which runs in a different thread. Protect modifications to
        // mActivities to avoid race.
        synchronized (mResourcesManager) {
            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;
}
​

上面代码code1处是发动windowManagerGlobal,因为windowManagerGlobal是单例形式,所以,一般认为windowManagerGlobal的初始化便是在此刻,其实便是为activity预备WindowManagerService。在code2处,将履行performLaunchActivity,咱们仔细阅览performLaunchActivity的函数会不难发现 code3处创立了一个activity实例方针。然后履行到code4处,此处履行了activity的attach 生命周期,在这个生命周期里边,构建了activity的仅有的phoneWindow方针,并且并绑定对应的WindowManager方便后期运用。然后代码会履行到code5,在code5里边便是调用Activity的onCreate生命周期的进程,一同mLifecycleState被设置为ON_CREATE,这个情况在后面履行第26步的时分将会用到。

1.4.2 履行executeLifecycleState函数

上面首要介绍了 TransactionExecutor#execute履行executeCallbacks的进程,下面咱们一同介绍一下履行executeLifecycleState的进程,也便是履行第24步到31步的进程。

private void executeLifecycleState(ClientTransaction transaction) {
    //获取ActivityLifecycleItem,咱们知道这儿获取的是咱们之前增加的ResumeActivityItem
    //其值是由第14步ActivityStackSupervisor中的realStartActivityLocked函数
    final ActivityLifecycleItem lifecycleItem =     
      transaction.getLifecycleStateRequest();
    if (lifecycleItem == null) {
      // No lifecycle request, return early.
      return;
     }
​
    final IBinder token = transaction.getActivityToken();
    final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
    if (DEBUG_RESOLVER) {
      Slog.d(TAG, tId(transaction) + "Resolving lifecycle state: "
          + lifecycleItem + " for activity: "
          + getShortActivityName(token, mTransactionHandler));
     }
​
    if (r == null) {
      // Ignore requests for non-existent client records for now.
      return;
     }
​
    // Cycle to the state right before the final requested state.
    //code1 要害点,ResumeActivityItem的getTargetState 是 ON_RESUME
    cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, 
          transaction);
​
    // Execute the final transition with proper parameters.
    //code2 履行 ResumeActivityItem 的 execute
    lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
    lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
​

从上面的代码,咱们发现code1处有一个十分重要的函数cycleToPath(),其间的 lifecycleItem.getTargetState() 回来值是 ON_RESUME。

private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
      ClientTransaction transaction) {
    //这儿在performLaunchActivity设置了LifecycleState为ON_CREATE,即:start是ON_CREATE,
    final int start = r.getLifecycleState();
    if (DEBUG_RESOLVER) {
      Slog.d(TAG, tId(transaction) + "Cycle activity: "
          + getShortActivityName(r.token, mTransactionHandler)
          + " from: " + getStateName(start) + " to: " + getStateName(finish)
          + " excludeLastState: " + excludeLastState);
     }
    //这儿的 start 是 ON_CREATE,finish 是 ON_RESUME
    //经过 mHelper 调用 getLifecyclePath 回来的 path 是 ON_START,下面会有解析
    //这儿是 Activity 履行 onStart 函数的要害地点
    final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
    //履行path中的相关的生命周期函数
    performLifecycleSequence(r, path, transaction);
}
​
private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
      ClientTransaction transaction) {
    //经过mHelper调用getLifecyclePath回来的path 是 ON_START
    final int size = path.size();
    for (int i = 0, state; i < size; i++) {
      state = path.get(i);
      if (DEBUG_RESOLVER) {
        Slog.d(TAG, tId(transaction) + "Transitioning activity: "
            + getShortActivityName(r.token, mTransactionHandler)
            + " to state: " + getStateName(state));
       }
      switch (state) {
        case ON_CREATE:
          mTransactionHandler.handleLaunchActivity(r, mPendingActions,
              null /* customIntent */);
          break;
        case ON_START:
          mTransactionHandler.handleStartActivity(r, mPendingActions);
          break;
        case ON_RESUME:
          mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
              r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
          break;
        case ON_PAUSE:
          mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
              false /* userLeaving */, 0 /* configChanges */, mPendingActions,
              "LIFECYCLER_PAUSE_ACTIVITY");
          break;
        case ON_STOP:
          mTransactionHandler.handleStopActivity(r.token, false /* show */,
              0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
              "LIFECYCLER_STOP_ACTIVITY");
          break;
        case ON_DESTROY:
          mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
              0 /* configChanges */, false /* getNonConfigInstance */,
              "performLifecycleSequence. cycling to:" + path.get(size - 1));
          break;
        case ON_RESTART:
          mTransactionHandler.performRestartActivity(r.token, false /* start */);
          break;
        default:
          throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
       }
     }
}
​
//TransactionExecutorHelper.java
//excludeLastState 为 true, start 为 ON_CREATE(1),finish 为 ON_RESUME(3)
public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {
    if (start == UNDEFINED || finish == UNDEFINED) {
      throw new IllegalArgumentException("Can't resolve lifecycle path for undefined state");
     }
    if (start == ON_RESTART || finish == ON_RESTART) {
      throw new IllegalArgumentException(
          "Can't start or finish in intermittent RESTART state");
     }
    if (finish == PRE_ON_CREATE && start != finish) {
      throw new IllegalArgumentException("Can only start in pre-onCreate state");
     }
​
    mLifecycleSequence.clear();
    if (finish >= start) {//走到此分支
      // just go there
      for (int i = start + 1; i <= finish; i++) {
      //把 ON_START 和 ON_RESUME 增加到 mLifecycleSequence 中
        mLifecycleSequence.add(i);
       }
     } else { // finish < start, can't just cycle down
       ......
     }
​
    // Remove last transition in case we want to perform it with some specific params.
    // 要害点:因为 excludeLastState 为 true,所以删除去 ON_RESUME 情况
    if (excludeLastState && mLifecycleSequence.size() != 0) {
      mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
     }
​
    return mLifecycleSequence;
   }
​

经过以上代码逻辑结构,咱们不难发现,整个进程是根据activity 的lifecycle的初始情况以及方针情况来进行运算,找到中心需求呼应的其他生命周期情况,也便是核算从ON_CREATE作为start的情况(在ActivityThread 中履行performLaunchActivity的进程中设置的),到以ON_RESUME作为生命周期结束情况,然后核算其间还需求经历的生命周期进程,也便是ON_START情况的进程。其实这也便是为什么activity生命周期被封装成为触发器Transaction的进程。

然后,咱们再重新回到executeLifecycleState的履行,当这个函数履行完结cycleToPath函数之后(里边会触发ActivityThread的handleStartActivity去履行acitivty的onStart 生命周期)就会运转到code2部分的代码进行运转lifecycleItem.execute(mTransactionHandler, token, mPendingActions)。lifecycleItem在executeLifecycleState 中咱们知道lifecycleItem的值是ResumeActivityItem,此刻代码就会运转到ResumeActivityItem#execute(),也便是第29步。最终会调用ActivityThread的handleResumeActivity(),从而履行Activity的onResume生命周期。

1.4.3 小结

在本阶段,首要是在Application进程经过跨进程接纳从AMS封装好的ClientTransaction方针,ClientTransaction方针里边封装了需求App进程履行Activity生命周期的一切的事情,然后在activity地点的进程中,依照触发器的触发逻辑,顺序的履行activity的 创立->attach->onCreate->onStart->onResume生命周期。

在AMS进程中的会经过ActivityStackSupervisor将activity发动相关的事情封装成为一个ClientTransaction方针,然后由ClientLifecycleManager经过ClientTransaction的函数将ClientTransaction方针以跨进程通信的办法传递给ApplicationThread。在完结了跨进程后,这个触发器所带着的指令就会在Application进程中得到触发。Application地点的进程会经过Handler来发动触发器TransactionExecutor的履行。TransactionExecutor会依照AMS中设置的逻辑,逐步去分发Activity的生命周期,直到整个触发器所带着的生命周期情况被履行完结停止,也便是onResume情况得到履行停止。

1.5 发动Activity的Activity onPause生命周期的运转

在Activity A 发动Activity B的时分,当Activity B发动流程履行到onResume生命周期之后,这个时分Activity A才会去履行它的onPause生命周期,这个逻辑是怎样的呢?咱们看下面的代码。

ActivityThread.java
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
    String reason) {
   ......
  // 回调 onResume
  final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
   ......
  final Activity a = r.activity;
   ......
  if (r.window == null && !a.mFinished && willBeVisible) {
     ......
    if (a.mVisibleFromClient) {
      if (!a.mWindowAdded) {
        a.mWindowAdded = true;
                // 增加 decorView 到 WindowManager
        wm.addView(decor, l);
       } else {
        a.onWindowAttributesChanged(l);
       }
     }
   } else if (!willBeVisible) {
     ......
   }
   ......
​
  // 主线程闲暇时会履行 Idler
  Looper.myQueue().addIdleHandler(new Idler());
}
​

在代码最终有一句代码:Looper.myQueue().addIdleHandler(new Idler())。IdleHandler 不知道咱们是否了解,它供给了一种机制,当主线程音讯行列闲暇时,会履行 IdleHandler 的回调办法,假如不懂这个逻辑的能够找一下其他handler章节的内容进行学习。messageQueue 中在正常的音讯处理机制之后,额外对 IdleHandler 进行了处理。当从Messagequeue中调用next函数去取Message时,在本次取到的 Message 为空或许需求延时处理的时分,就会去履行 mIdleHandlers 数组中的 IdleHandler 方针。所以,不出意外的话(主线程很忙),当新的 Activity 完结页面绘制并显现之后,主线程就能够停下歇一歇,来履行 IdleHandler 了。再回来 handleResumeActivity() 中来,Looper.myQueue().addIdleHandler(new Idler()) ,这儿的 Idler 是 IdleHandler 的一个具体实现类。

private class Idler implements MessageQueue.IdleHandler {
    @Override
    public final boolean queueIdle() {
        ActivityClientRecord a = mNewActivities;
        boolean stopProfiling = false;
        if (mBoundApplication != null && mProfiler.profileFd != null
                && mProfiler.autoStopProfiler) {
            stopProfiling = true;
        }
        if (a != null) {
            mNewActivities = null;
            IActivityTaskManager am = ActivityTaskManager.getService();
            ActivityClientRecord prev;
            do {
                if (localLOGV) Slog.v(
                    TAG, "Reporting idle of " + a +
                    " finished=" +
                    (a.activity != null && a.activity.mFinished));
                if (a.activity != null && !a.activity.mFinished) {
                    try {
                        // code1 调用 AMS.activityIdle()
                        am.activityIdle(a.token, a.createdConfig, stopProfiling);
                        a.createdConfig = null;
                    } catch (RemoteException ex) {
                        throw ex.rethrowFromSystemServer();
                    }
                }
                prev = a;
                a = a.nextIdle;
                prev.nextIdle = null;
            } while (a != null);
        }
        if (stopProfiling) {
            mProfiler.stopProfiling();
        }
        applyPendingProcessState();
        return false;
    }
}
​

上面的代码在code1处调用AMS 的activityIdle(),这个时分就顺利的将代码的履行转移到了AMS地点的进程中。

每日一题:Activity启动流程分析

图 29-5

经过上图咱们不难发现:上面的流程证明,咱们activity的stop和destroy生命周期在此处履行。也便是说此刻会履行发动activity之前的上一个activity的onStop生命周期,或许onDestroy生命周期。当然,假如咱们具体的剖析ActivityStackSupervisor(ASS)的代码,咱们会不难发现一个细节,等待毁掉的Activity被保存在了 ASS 的 mStoppingActivities 集合中,它是一个 ArrayList。

1.5.1 小结

Activity 的 onStop/onDestroy 是依靠 IdleHandler 来回调的,正常情况下当主线程闲暇时会调用。但是因为某些特殊场景下的问题,导致主线程迟迟无法闲暇,onStop/onDestroy 也会迟迟得不到调用。但这并不意味着 Activity 永远得不到回收,体系供给了一个兜底机制,当 onResume 回调 10s 之后,假如依然没有得到调用,会自动触发。

1.6 总结

Activity的发动交由ATMS触发处理,在Activity发动前需求先在ActivityStarter类中解读包含Activity的发动形式在内的各种参数信息。确定好发动信息后经过创立一个黑白屏的办法反馈给用户一个信息:咱们正在呼应发动app的进程中。然后将发动流程转交给ActivityStack处理,因为在ActivityStack中存储了一个Application的一切Activity,因而在此刻运用的各Activity应该怎么呼应需求由ActivityStack来共同安排,在这个进程中就必定涉及到Activity的pause和需求发动的Activity的“realstart”。为了更好的办理Activity发动进程中的各生命周期,在ActivityStackSupervisor里边会将生命周期的事情封装成为一个ClientTransaction,并将这个ClientTransaction的方针经过跨进程的办法发送给App进程,然后由app进程的TransactionExecutor共同去触发履行,直到完结Activity的onResume生命周期停止,总流程如下图所示。

每日一题:Activity启动流程分析

今日共享到此结束,对你有帮助的话,点个赞再走呗,下期更精彩~

重视公众号:Android老皮
解锁 《Android十大板块文档》 ,让学习更靠近未来实战。已形成PDF版

内容如下

1.Android车载运用开发体系学习指南(附项目实战)
2.Android Framework学习指南,助力成为体系级开发高手
3.2023最新Android中高档面试题汇总+解析,告别零offer
4.企业级Android音视频开发学习道路+项目实战(附源码)
5.Android Jetpack从入门到精通,构建高质量UI界面
6.Flutter技能解析与实战,跨渠道首要之选
7.Kotlin从入门到实战,全方面提高架构基础
8.高档Android插件化与组件化(含实战教程和源码)
9.Android 功能优化实战+360全方面功能调优
10.Android零基础入门到精通,高手进阶之路

敲代码不易,重视一下吧。ღ( ・ᴗ・` )