深入Android系统(十一)AMS-2-Activity生命周期管理

Activity管理

Activity是最复杂的一个组件,它负责UI的显示以及处理各种输入事件。Activity提供窗口供应用在其中绘制界面,同时也提供了各种各样的控件方便开发。Activity 官网传送门

另外,Android中并没有对外提供启动进程的接口,只是在启动ActivityService时,由系统根据需要来启动进程。

Activity的生命周期

关于Activity的生命周期,我们先看下官方图示:
image

Activity的生命周期图中隐含了Activity运行时的三种状态,分别是:

  • 激活态:新启动的Activity位于屏幕的最前端,可以接受用户输入的状态
  • 暂停态:当Activity被一个透明或半透明的Activity覆盖,此时Activity虽然不能接收用户的输入,但还是可见的
  • 停止态:当一个Activity完全被另一Activity覆盖,不能接受用户输入也不可见时

当一个Activity对象的状态发生变化时,会调用上图中定义的抽象接口来通知应用。相关描述如下:

  • onCreate():当Activity对象被创建时调用
  • onStart():当ActivityFramework中的数据结构准备完毕后调用
  • onResume():当Activity来到栈的最前端变成激活态时调用
  • onPause():当Activity从栈的最前端切换到后台时,进入暂停态,并调用该方法
  • onStop():当Activity已经完全不可见时调用
  • onDestroy():在销毁Activity前,系统会先调用该方法

上面的知识在初学Android时我们就已经知道了,接下来我们要从AMS的角度看下这几个方法是如何调用的,不过在此之前我们先熟悉下另外的几个相关知识:IntentTaskLaunchMode

IntentTaskLaunchMode

理解Intent

Intent是所请求执行动作的抽象描述,通常作为参数来使用,用于完成各个组件之间的消息传递。更为详细的姿势可以参考官网描述:官网传送门

Intent类的相关定义如下:

public class Intent implements Parcelable, Cloneable {
    private String mAction;
    private Uri mData;
    private String mType;
    private String mPackage;
    private ComponentName mComponent;
    private int mFlags;
    private ArraySet<String> mCategories;
    private Bundle mExtras;
    private Rect mSourceBounds;
    private Intent mSelector;
    private ClipData mClipData;
}

常用字段含义如下:

  • mAction是一个字符串,用来指明要执行的操作是什么。
    • Intent类中定义了大量的Action,例如ACTION_VIEWACTION_SEND等。
    • 这些Action的作用与具体的功能模块相关,表达要执行的意图
  • mData储存需要传递的数据,类型是URI
    • URI是统一资源标识符(Uniform Resources Identifier)的简称
    • 最初用于表示Web中的各种资源,如HTML文档、图片、文件等
    • URL(Uniform Resource Locator)URI的一种
  • mTypeMIME格式的字符串,表示数据类型。
    • MIME是多功能Internet邮件扩充服务(Multipurpose Internet Mail Extensions)的缩写
    • 最早英语电子邮件系统,后来应用到浏览器。格式例如:text/plain``application/x-gzip
    • 通常该数据类型不需要指定,如果设置了这个字段,可以加快Intent的匹配速度
  • mComponent用于指定接收Intent的目标组件的名称
    • mComponent的类型是ComponentName,它包含两个字符串:mPackagemClass,前者用于指定包名,后者用于指定类名
    • Intent中如果定义了mComponent,该Intent将直接发送到指定的组件,不会在通过其他属性组合查找
  • mFlags称为标志,在Intent类中定义了很多flag的相关常量。主要分为两种
    • FLAG_ACTIVITY_...开头的,用来控制Activity启动的相关参数,如FLAG_ACTIVITY_NEW_TASK
    • FLAG_RECEIVER_...开头的,用来进行广播的参数
  • mCategories一个包含应处理Intent组件类型的附加信息的字符串。常见的类别有两种:
    • CATEGORY_BROWSABLE:目标Activity允许本身通过网络浏览器启动,以显示链接引用的数据
    • CATEGORY_LAUNCHER:该Activity是任务的初始Activity
    • 可以将任意数量的类别描述放入一个 Intent中,但大多数Intent均不需要类别
  • mExtras表示所有附加信息的集合。
    • mExtras数据类型是Bundle
    • 可以使用各种putExtra()方法添加extra数据,每种方法均接受两个参数:keyvalue

Task

TaskActivity的集合。Android把用户一次相关操作中使用的Activity按照先后顺序保存在Task中,这样当按back键时就能按照相反的顺序回退。

Task像一个栈,以后进先出的方式管理着Activity。系统运行时内存中会存在着多个Task,当我们按recent键时,会弹出一个选择列表,这个列表就是系统中存在的Task的集合,选择一个Task将把它所包含的Activity作为一个整体带到前台。Task中的Activity的顺序通常是不能改变的,只能通过出栈入栈的方式来增加或移除。

AMS中使用ActivityStack来管理Task,它管理的Task都存放在成员变量mTaskHistory中,定义如下:

class ActivityStack{
    private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
}

mTaskHistory是一个列表,储存的是TaskRecord对象。TaskRecord对象表示一个Task,它的成员变量mActivities也是一个列表,储存了该Task中所有的ActivityRecord对象。mActivities的定义如下:

class TaskRecord{
    final ArrayList<ActivityRecord> mActivities;
}

那么,如何才能开始一个新的Task呢?

  • Intent中定义了一个标志FLAG_ACTIVITY_NEW_TASK,在startActivity()Intent参数中加入该标志就能开启一个新的Task
  • 但是如果系统中已经有相同affinityTask存在,并不会再启动一个Task,而是将旧的Task带到前台

那么,affinity在哪里定义的呢?

  • affinity的意思是亲和度,是通过<activity>标签的android:taskAffinity属性来定义的
  • 当使用标志FLAG_ACTIVITY_NEW_TASK启动一个Activity时,这个ActivitytaskAffinity属性中的字符串就会成为Taskaffinity
  • 以后加入这个TaskActivity,即使它们的taskAffinity属性定义了一个不同的字符串,也不会改变Task已有的affinity
  • 如果<activity>标签中没有指定android:taskAffinity属性,这个Activity会继承<application>标签的android:taskAffinity属性
  • 如果<application>标签的android:taskAffinity属性也没有定义,将会使用应用包名作为缺省值
    • 正因为如此,如果在应用中启动本应用的另一个Activity,即使使用了FLAG_ACTIVITY_NEW_TASK标志也不一定会启动一个新的Task
    • 除非这个Activity定义了不同的taskAffinity属性

LaunchMode

Activity的启动模式隐含的是Activity对象的复用问题,关于启动模式官网的介绍也很详细:官方传送门

当启动一个Activity时,如果系统的后台Task中已经有一个该Activity的实例存在了,系统是创建一个新的Activity还是将已经存在的Activity切换到前台呢?

答案是都有可能,有多种因素可以影响结果。包括Activity的属性值以及Intent中指定的标志

我们先看下Activity的属性launchMode会有哪些影响:

  • standard模式:默认。
    • standard模式下的Activity每次启动时都会创建该Activity的实例对象
    • 同一个Task中可以同时存在该Activity的多个实例
    • 一个Activity的多个实例可以出现在多个Task栈中
  • singleTop模式
    • 如果目标Task的顶部已存在该Activity实例,则系统会通过调用该实例的onNewIntent()方法向其传送Intent,而非创建新的Activity实例。
    • 如果不在栈顶,这standard模式一样创建新的实例对象
  • singleTask模式
    • 设置singleTask模式的Activity具有系统唯一性,只能在系统中创建该Activity的一个实例对象
    • 启动设置为singleTask模式的Activity时,如果系统中已经存在该Activity的实例对象,则将其所在的Task中排在它前面的Activity都弹出栈,将该Activity带到栈顶,并调用其onNewIntent()方法传递新的Intent对象
    • 如果系统中不存在该Activity的实例对象,则会创建一个该Activity的实例对象
      • 如果该ActivitytaskAffinity属性值和当前Taskaffinity值相同,它会加入当前的Task
      • 否则,即使启动该ActivityIntent中没有指定FLAG_ACTIVITY_NEW_TASK标志,也会启动新的Task,并将Activity至于其中
  • singleInstance模式
    • 设置为singleInstance模式的Activity同样具有系统唯一性,系统中只有该Activity的一个实例对象
    • 同时系统不会将任何其他Activity启动到包含该Activity实例的Task
    • Activity始终是其Task中的唯一Activity

通常情况下,一个Activity创建出来后,会停留在某个Task中,直到它被销毁

  • 但是,如果ActivityallowTaskReparenting属性设置为true,该Activity可以在不同的Task之间转移
  • 不过,这个属性只有在启动ActivityIntent中设置了FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标志时才起作用

除了上面介绍的内容,ActivityTask的工作逻辑大家可以参考官网:任务和返回堆栈

比如,下面部分提到的技巧就很重要(摘抄自官网):

只有当 Activity 具有 ACTION_MAIN 和 CATEGORY_LAUNCHER 过滤器时,才应使用 “singleTask” 和 “singleInstance” 这两种启动模式,它们会将 Activity 标记为始终启动任务。比如,可以想象一下,如果缺少该过滤器会发生什么情况:intent 会启动 “singleTask” Activity,随之启动新任务,用户花了一些时间在该任务上。然后,用户按主屏幕按钮。此时,该任务会转到后台,不再可见。现在,用户无法返回到该任务,因为它未显示在应用启动器中。

了解ClientTransactionHandler的作用

ClientTransactionHandler是在Android 9.0上出现的,用来串联起AMSActivity的整个生命周期管理的类,很重要

我们已经知道应用的入口是ActivityThread类的main()函数,仔细看下类结构的话会发现要ActivityThread继承了一个特殊的类。定义如下

public final class ActivityThread extends ClientTransactionHandler {
    ...
}

可以看到ActivityThread继承了ClientTransactionHandler类。这个类是在Android 9.0加入的,关键定义如下:

public abstract class ClientTransactionHandler {
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
    ......
    public abstract void handleDestroyActivity(...);
    public abstract void handlePauseActivity(...);
    public abstract void handleResumeActivity(...);
    public abstract void handleStopActivity(...);
    ......
    public abstract Activity handleLaunchActivity(...);
    public abstract void handleStartActivity(...);
    ......
    public abstract void handleNewIntent(...);
    ......
}

类中定义了和声明周期有关的方法,机智的我们可以猜到,AMS后面生命周期的回调控制应该就是通过它来实现的,相关类继承关系如下:
image

可以AndroidActivity相关的生命周期要做的事情抽象了出来,在上面定义的类中,真正业务实现包括:

  • LaunchActivityItem就是要执行launch activity任务
  • resume activity则是通过ResumeActivityItem实现
  • pause activity则是通过PauseActivityItem实现
  • stop activity则是通过StopActivityItem实现
  • destroy activity则是通过DestoryActivityItem实现

ClientTransaction的调用逻辑

我们看下整个调用流程:
ActivityThread中的ApplicationThread类有一个scheduleTransaction()方法,

ApplicationThread类是一个Binder服务类,AMS会作为client调用这个服务类,当然也就可以调用它的scheduleTransaction()方法

scheduleTransaction()方法内容如下:

@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction);
}

调用的是ActivityThreadscheduleTransaction()方法,也就是ClientTransactionHandler类的scheduleTransaction()方法,方法如下:

    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

发送了一个EXECUTE_TRANSACTION消息给ActivityThreadHandler实现类H,消息处理如下:

case EXECUTE_TRANSACTION:
    final ClientTransaction transaction = (ClientTransaction) msg.obj;
    mTransactionExecutor.execute(transaction);
    if (isSystem()) {
        transaction.recycle();
    }
    break;

消息处理中使用了mTransactionExecutor.execute(),不出意外,执行逻辑肯定在TransactionExecutor中了,我们看下:

    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        executeCallbacks(transaction);
        executeLifecycleState(transaction);
        mPendingActions.clear();
    }
    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        if (callbacks == null) {
            return;
        }
        ......
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            ......
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            ......
        }
    }
    private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }
        ......
        // 很重要的一个方法
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);
        // Execute the final transition with proper parameters.
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

可以看到,最后分别在executeCallbacks()executeLifecycleState()两个方中执行了item.execute()lifecycleItem.execute()两个方法

executeCallbacks()executeLifecycleState()目的分别是干什么呢?结合类关系图我们可以这样推断:

  • executeCallbacks()遍历执行的是ClientTransaction类中List<ClientTransactionItem> mActivityCallbacks集合中的元素
    • ClientTransactionItem类的直接子类实现只有LaunchActivityItem
    • 也就是说executeCallbacks()主要执行的是launch activity的通知操作
  • executeLifecycleState()执行的是ClientTransaction类中的ActivityLifecycleItem mLifecycleStateRequest
    • mLifecycleStateRequest被称为final state
    • 从继承关系上可以看到,resume activitypasue activitystop activitydestory activity都在这里

了解完调用流程会发现,实现类中并没有StartActivityItem,为什么呢?那怎么调用onStart()函数呢?
核心就在cycleToPath()函数身上

TransactionExecutor.cycleToPath()

针对Activity的生命周期,Android并没有定义出所有的*ActivityItem类,例如StartActivityItem就并不存在,那么怎么去执行这个start阶段的函数呢?

请留意类图中ActivityLifecycleItem有关生命周期的常量定义,Android在这里通过cycleToPath()采用了一种比较取巧的操作,核心逻辑就是:

  • 指定一个Activityfinal state
  • 根据Activity的当前状态去计算过程中需要的状态,并保存到集合中
  • 最后按顺序执行集合中的状态

以文章后面的realStartActivityLocked()方法为例

  • LaunchActivityItem类型的对象添加到callback
    • TransactionExecutor会先执行LaunchActivityItem
    • 执行完后Activity进入到ON_CREATE状态
  • 方法中指定了final stateResumeActivityItem
    • TransactionExecutor通过cycleToPath()计算当前状态与final state的差异
    • 当前状态为ON_CREATE状态,final stateON_RESUME
    • TransactionExecutor通过帮助类的getLifecyclePath方法将两者之间缺失的状态整理到集合中
    • 然后调用performLifecycleSequence()循环处理

performLifecycleSequence()方法如下:

    private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            switch (state) {
                case ON_CREATE:
                    mTransactionHandler.handleLaunchActivity(...);
                    break;
                case ON_START:
                    mTransactionHandler.handleStartActivity(r, mPendingActions);
                    break;
                case ON_RESUME:
                    mTransactionHandler.handleResumeActivity(...);
                    break;
                case ON_PAUSE:
                    mTransactionHandler.handlePauseActivity(...);
                    break;
                case ON_STOP:
                    mTransactionHandler.handleStopActivity(...);
                    break;
                case ON_DESTROY:
                    mTransactionHandler.handleDestroyActivity(...);
                    break;
                case ON_RESTART:
                    mTransactionHandler.performRestartActivity(...);
                    break;
                default:
                    throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
            }
        }
    }

PauseActivityItem的调用分析

PauseActivityItem类为例,我们看看具体的执行逻辑:

public class PauseActivityItem extends ActivityLifecycleItem {
    ......
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        ......
        client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
                "PAUSE_ACTIVITY_ITEM");
        ......
    }
}

执行的是ClientTransactionHandler抽象类,其实也就是ActivityThread类的handlePauseActivity()方法。

handlePauseActivity()方法调用了ActivityThread类的performPauseActivity()方法,最后调用到的是performPauseActivityIfNeeded()方法,代码如下:

    private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
        ......
        mInstrumentation.callActivityOnPause(r.activity);
        ......
    }

执行的是Instrumentation类的callActivityOnPause()方法,内容如下:

    public void callActivityOnPause(Activity activity) {
        activity.performPause();
    }

很简洁,继续查看:

public class Activity{
    final void performPause() {
        mDoReportFullyDrawn = false;
        mFragments.dispatchPause();
        mCalled = false;
        onPause();
        writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause");
        mResumed = false;
        ......
    }
}

有木有!有木有!onPause();终于调用到了。。。。。。

我们已经从应用端找到了调用的流程,但是,对于AMS来说它是怎么触发的呢?

接下来,我们分析下Activity的启动,在Activity启动的过程我们就可以找到AMS触发声明周期的例子

启动Activity

研究Activity生命周期的调用细节,我们还是得从最熟悉的地方入手,也就是常用的Activity对象的startActivity (Intent intent)方法

Activty.startActivty()

跟踪startActivity (Intent intent)方法,发现调用关系如下:

class Activity{
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            startActivityForResult(intent, -1);
        }
    }
    public void startActivityForResult(...) {
        ......
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, who,
                intent, requestCode, options);
        ......
    }
}
class Instrumentation{
    public ActivityResult execStartActivity(...) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        ......
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManager.getService()
                .startActivity(...);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }
}
class ActivityManagerService{
    public final int startActivity(...) {
        return startActivityAsUser(...);
    }
    public final int startActivityAsUser(...) {
        ......
        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                ...
                .execute();
    }
}

我们看到最后是调用的是AMSstartActivityAsUser方法。跟踪startActivityAsUser方法的调用过程就会发现最后执行的是ActivityStarter类的execute()方法来执行Activity的启动,相关代码如下:

class ActivityStater{
    int execute() {
        try {
            if (mRequest.mayWait) {
                return startActivityMayWait(...);
            } else {
                return startActivity(...);
            }
        } finally {
            onExecutionComplete();
        }
    }
}

我们看到execute()有两个启动Activity的方法,接下来我们以startActivityMayWait()方法继续分析,因为最后也会走到startActivity()中。

ActivityStarter.startActivityMayWait()

简要代码如下:

private int startActivityMayWait(...) {
    ......
    // 获取要启动的 Activity 的信息
    ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
    synchronized (mService) {
        ......
        int res = startActivity(caller, ...);
        ......
        if (outResult != null) { // 需要返回结果
            outResult.result = res;
            final ActivityRecord r = outRecord[0];
            switch(res) {
                case START_SUCCESS: {
                    // 添加到特定集合中
                    mSupervisor.mWaitingActivityLaunched.add(outResult);
                    do {
                        try {
                            // 等待应用进程中的 Activity 启动完成
                            mService.wait();
                        } catch (InterruptedException e) {
                        }
                    } while (outResult.result != START_TASK_TO_FRONT
                            && !outResult.timeout && outResult.who == null);
                    ......
                    break;
                }
                ......
            }
        }
        return res;
    }
}

startActivityMayWait()方法的流程如下:

  • 首先调用resolveActivity()方法来获取要启动的Activity的信息
  • 得到Activity的信息后,继续调用startActivity()方法来继续启动Activity
  • 如果启动Activity的应用需要获取返回结果,则调用mService对象的wait()方法挂起线程等待启动的结果

接下来就是调用ActivityStarterstartActivity()方法的代码,我们看下部分细节:

private int startActivity(IApplicationThread caller, ...) {
    int err = ActivityManager.START_SUCCESS;
    ......
    if (caller != null) {
        // 获取启动Activity的进程的信息
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
        } else {
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }
    final int userId = aInfo != null && aInfo.applicationInfo != null
            ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
    ......// 省略很多错误检查
    // 检查调用者的相关权限
    boolean abort = !mSupervisor.checkStartAnyActivityPermission(...);
    // 检查 Intent 防火墙是否屏蔽了该 Intent
    abort |= !mService.mIntentFirewall.checkStartActivity(...);
    ......
    if (mService.mController != null) {
        try {
            // 将 Activity 启动的消息通知监听系统Activity变动的接口 IActivityControler
            Intent watchIntent = intent.cloneFilter();
            abort |= !mService.mController.activityStarting(watchIntent,
                    aInfo.applicationInfo.packageName);
        } catch (RemoteException e) {
            mService.mController = null;
        }
    }
    ......
    if (abort) {
        ......// 如果 abort 为true,直接退出
        return START_ABORTED;
    }
    ......
    // 创建 ActivityRecord  对象
    ActivityRecord r = new ActivityRecord(...);
    if (outActivity != null) {
        outActivity[0] = r;
    }
    ......
    // 当前用户正在操作的 ActivityStack
    final ActivityStack stack = mSupervisor.mFocusedStack;
    // 针对经常切换进程的情况,检查调用者是否有权限进行进程切换
    if (voiceSession == null && (stack.getResumedActivity() == null
            || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
        if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
                realCallingPid, realCallingUid, "Activity start")) {
            // 对于不能切换进程的情况,把 Activity 信息放入 mPendingActivityLaunches 列表中
            mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
                    sourceRecord, startFlags, stack, callerApp));
            ActivityOptions.abort(checkedOptions);
            return ActivityManager.START_SWITCHES_CANCELED;
        }
    }
    if (mService.mDidAppSwitch) {
        mService.mAppSwitchesAllowedTime = 0;
    } else {
        mService.mDidAppSwitch = true;// 打开开关,允许进程间切换
    }
    // 启动挂起等待的 Activity,其实就是逐个启动 mPendingActivityLaunches 列表中的 Activity。
    // 最后也是调用了 startActivity
    // 个人理解,大多数情况下 mPendingActivityLaunches 列表应该是空的吧
    mController.doPendingActivityLaunches(false);
    ......
    // 调用startActivity另一个重载方法,第一个参数为 ActivityRecord
    return startActivity(r, ...);
}
private int startActivity(final ActivityRecord r, ...) {
    int result = START_CANCELED;
    ......
    result = startActivityUnchecked(r, ...);
    ......
    return result;
}

这里其实不用记录太多细节,重要的是了解启动Activity方法的调用流程,这里最后调用的是startActivityUnchecked()方法,我们来继续看下。

ActivityStarter.startActivityUnchecked()

方法如下:

private int startActivityUnchecked(final ActivityRecord r, ...) {
    // 初始化环境和lunchModeFlags   
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
            voiceInteractor);
    computeLaunchingTaskFlags();
    computeSourceStack();
    mIntent.setFlags(mLaunchFlags);

    // 判断 Activity 是否需要插入新的 Task,以下情况 reusedActivity 不为空
    // 1.设置了FLAG_ACTIVITY_NEW_TASK:
    // 2.启动模式为singleTask:
    // 3.启动模式为singleInstance
    ActivityRecord reusedActivity = getReusableIntentActivity();
    ......
    final boolean dontStart = top != null && mStartActivity.resultTo == null
            && top.realActivity.equals(mStartActivity.realActivity)
            && top.userId == mStartActivity.userId
            && top.app != null && top.app.thread != null
            && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
            || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
    if (dontStart) { // 不需要启动的情况
        // For paranoia, make sure we have correctly resumed the top activity.
        topStack.mLastPausedActivity = null;
        if (mDoResume) {
            mSupervisor.resumeFocusedStackTopActivityLocked();
        }
        ......
        deliverNewIntent(top);
        ......
        return START_DELIVERED_TO_TOP;
    }
    boolean newTask = false;
    final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
            ? mSourceRecord.getTask() : null;
    // 判断当前 Activity 是否需要一个新的 Task
    int result = START_SUCCESS;
    if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
            && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
        newTask = true;
        result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
    } else if (mSourceRecord != null) {
        result = setTaskFromSourceRecord();
    } else if (mInTask != null) {
        result = setTaskFromInTask();
    } else {
        // This not being started from an existing activity, and not part of a new task...
        // just put it in the top task, though these days this case should never happen.
        setTaskToCurrentTopOrCreateNewTask();
    }
    ......
    // 启动 Activity
    // startActivityLocked 这里主要是将 ActivityRecord 对象加入到 Task 的顶部
    // 同时将 Task 添加到 mTaskHistory 的顶部
    mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
            mOptions);
    // 利用 WindowManager 使 Activity 可见
    if (mDoResume) {
        final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked();
        if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay && mStartActivity != topTaskActivity)) {
            mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
            mService.mWindowManager.executeAppTransition(); // 此处应该是执行应用间的切换动画
        } else {
            .......
            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                    mOptions);
        }
    } else if (mStartActivity != null) {
        mSupervisor.mRecentTasks.add(mStartActivity.getTask());
    }
    ......
    return START_SUCCESS;
}

startActivityUnchecked()方法主要是通过Intent的标志和Activity的属性来确定ActivityTask,然后将其调整至栈顶,细节我们先略过,需要重点关注的方法是mSupervisor.resumeFocusedStackTopActivityLocked()方法的调用。跟踪调用就会发现,最后执行的是ActivityStack类的resumeTopActivityInnerLocked()方法

ActivityStack.resumeTopActivityInnerLocked()

我们前面已经知道resumeFocusedStackTopActivityLocked()方法最终会调用ActivityStack类的resumeTopActivityInnerLocked()方法。

resumeTopActivityInnerLocked()方法主要的作用是将位于栈顶的Activity显示出来,不过在此之前,旧的Activity(变量mResumedActivity引用的就是)还显示在屏幕上。方法内容如下:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    if (!mService.mBooting && !mService.mBooted) {
        // Not ready yet!
        return false;
    }
    // 从要 mTaskHistory 中查找要启动的 Activity
    // 这里这样做应该是因为前面已经将 Activity 放入堆栈中了
    final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
    final boolean hasRunningActivity = next != null;
    ......
    if (!hasRunningActivity) {
        // There are no activities left in the stack, let's look somewhere else.
        return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");
    }
    next.delayedResume = false;
    // 如果当前显示的 Activity 就是要启动的 Activity,直接返回
    if (mResumedActivity == next && next.isState(RESUMED)
            && mStackSupervisor.allResumedActivitiesComplete()) {
        executeAppTransition(options);
        return false;
    }
    // 如果正在休眠或者关机,直接返回
    if (shouldSleepOrShutDownActivities()
            && mLastPausedActivity == next
            && mStackSupervisor.allPausedActivitiesComplete()) {
        executeAppTransition(options);
        return false;
    }
    // user 状态检查
    if (!mService.mUserController.hasStartedUserState(next.userId)) {
        return false;
    }
    // 将要启动的 Activity 从相关队列中移除
    mStackSupervisor.mStoppingActivities.remove(next);
    mStackSupervisor.mGoingToSleepActivities.remove(next);
    next.sleeping = false;
    mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);
    // 检查是否有正在 Pause 的 Activity
    if (!mStackSupervisor.allPausedActivitiesComplete()) {
        return false;
    }
    // 设置要启动的 applicationInfo
    mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
    ......
    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
    if (mResumedActivity != null) {
        // 暂停当前 Activity
        // startPausingLocked() 中便会触发 旧Activity 的 onPause() 操作
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }
    ......
    ActivityStack lastStack = mStackSupervisor.getLastStack();
    if (next.app != null && next.app.thread != null) {
        // 如果 Activity 所在的应用已经存在,只需要把 Activity 显示出来
        ......
        synchronized(mWindowManager.getWindowManagerLock()) {
            // This activity is now becoming visible.
            if (!next.visible || next.stopped || lastActivityTranslucent) {
                next.setVisibility(true);
            }
            ......
            try {
                final ClientTransaction transaction = ClientTransaction.obtain(next.app.thread,
                        next.appToken);
                ......
                // 如果当前 Activity 还有等待返回的结果,添加 ActivityResultItem,
                // 其中会执行 onActivityResult 回调
                ArrayList<ResultInfo> a = next.results;
                if (a != null) {
                    final int N = a.size();
                    if (!next.finishing && N > 0) {
                        if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                                "Delivering results to " + next + ": " + a);
                        transaction.addCallback(ActivityResultItem.obtain(a));
                    }
                }
                // 添加 NewIntentItem,其中会执行 onNewIntent
                if (next.newIntents != null) {
                    transaction.addCallback(NewIntentItem.obtain(next.newIntents,
                            false /* andPause */));
                }
                transaction.setLifecycleStateRequest(
                        ResumeActivityItem.obtain(next.app.repProcState,
                                mService.isNextTransitionForward()));
                mService.getLifecycleManager().scheduleTransaction(transaction);
                ......
            } catch (Exception e) {
                // Whoops, need to restart this activity!
                ......
                mStackSupervisor.startSpecificActivityLocked(next, true, false);
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return true;
            }
        }
        ......
    } else {
        // Whoops, need to restart this activity!
        ......
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }
    ......
    return true;
}

resumeTopActivityInnerLocked()代码比较长作了精简,核心逻辑如下:

  • 先是通过startPausingLocked()暂停旧的ActivitystartPausingLocked()方法如下:
    final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
            ActivityRecord resuming, boolean pauseImmediately) {
        ......
        mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
                        PauseActivityItem.obtain(prev.finishing, userLeaving,
                                prev.configChangeFlags, pauseImmediately));
        ......
    }
    
    • 这里四不四就和前面的ClientTransaction呼应上了,嘿嘿
  • 如果Activity所在的应用已经启动,对Activity进行显示处理,创建ResumeActivityItem进行生命周期通知
    • 最终会导致Activity对象的onResume()方法的执行
  • 如果应用还没有启动,则调用startSpecificActivityLocked()方法继续处理,方法如下:
    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // 获取 Activity 对应的进程
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
        if (app != null && app.thread != null) {
            try {
                ......
                // 如果应用进程已经存在的情况,执行 realStartActivityLocked() 
                // andResume = true
                realStartActivityLocked(r, app, andResume, checkConfig);
                // 然后返回
                return;
            } catch (RemoteException e) {
            }
    
        }
        // Activity 对应的进程为空,通过 AMS 的 startProcessLocked() 创建新的进程
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }
    
    • 核心方法是realStartActivityLocked(),就算是重新启动进程的情况,最后执行的也是realStartActivityLocked()

ActivityStackSupervisor.realStartActivityLocked()

对于realStartActivityLocked()方法,我们简单看下和生命周期相关的内容:

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
        ......
        // Create activity launch transaction.
        final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                r.appToken);
        // 添加 LaunchActivityItem,这个会触发 onCreate 方法
        clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), ...);
        // 设置最终状态,resume 还是 pause
        final ActivityLifecycleItem lifecycleItem;
        // 根据前面的调用参数可以确定,andResume = true
        if (andResume) {
            // 设置最终状态为 ON_RESUME
            lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
        } else {
            lifecycleItem = PauseActivityItem.obtain();
        }
        clientTransaction.setLifecycleStateRequest(lifecycleItem);
        // Schedule transaction.
        mService.getLifecycleManager().scheduleTransaction(clientTransaction);
        ......
        return true;
    }

方法中添加了LaunchActivityItemResumeActivityItem类的对象,并调用了scheduleTransaction()方法。

LaunchActivityItem属于比较复杂的调用逻辑

LaunchActivityItem类为例,我们来看跟踪下调用关系:

public class LaunchActivityItem extends ClientTransactionItem {
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        ......
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        ......
    }
}

调用的是ActivityThreadhandleLaunchActivity()的方法:

    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        ......
        final Activity a = performLaunchActivity(r, customIntent);
        ......
        return a;
    }
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ......
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
            ......
        } catch (Exception e) {
            ...
        }
        try {
            ......
            if (activity != null) {
                ......
                activity.mCalled = false;
                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;
            }
            // 将状态设置为 ON_CREATE
            r.setState(ON_CREATE);
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
            ......
        }
        return activity;
    }

调用的是Instrumentation.callActivityOnCreate()方法,内容如下:

    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }

最后通过是调用的Activity.performCreate()方法:

    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        ......
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        ......
    }

到这里,LaunchActivityItem的逻辑就结束了,也执行完了onCreate()回调,状态设置为了ON_CREATE

但是由于realStartActivityLocked()中设置的最终状态为ON_RESUME,当前Activity的状态不是最终状态,所以TransactionExecutor还会继续执行。

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Android 中,AMS(Activity Manager Service)负责管理 Activity生命周期Activity 有四个状态:运行状态、暂停状态、停止状态和销毁状态。当一个 Activity 运行时,它可以被用户看到,并响应用户的交互;当它被暂停时,它被部分遮挡,但仍然在屏幕上存在;当它被停止时,它被完全遮挡,但其状态仍然保留在内存中;当它被销毁时,它被完全删除,其状态也从内存中释放。 Activity 生命周期管理的关键是回调方法。Android 系统提供了一组回调方法,使得开发者可以在 Activity 的不同状态下执行相应的操作。 以下是 Activity 生命周期的回调方法: 1. onCreate(): Activity 被创建时调用,通常用来完成界面的初始化和数据的加载。 2. onStart(): Activity 变为可见时调用,此时 Activity 进入运行状态。 3. onResume(): Activity 处于前台并处于运行状态时调用,此时 Activity 可以响应用户的交互。 4. onPause(): 当其他 Activity 显示在前台并且当前 Activity 处于可见状态时调用,此时 Activity 进入暂停状态。 5. onStop(): Activity 完全被遮挡时调用,此时 Activity 进入停止状态。 6. onRestart(): 当 Activity 从停止状态重新进入运行状态时调用。 7. onDestroy(): Activity 被销毁时调用,通常用来释放内存或资源。 开发者应根据自己的应用需求在这些回调方法中编写相应的业务逻辑,从而实现自己的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值