Activity启动流程总结

本文详细解析了Android中Activity的启动流程,包括根Activity、子Activity在进程内及跨进程的启动过程。从Launcher启动MainActivity的六个关键步骤出发,深入探讨了ActivityManagerService在启动流程中的核心作用,以及涉及的主要方法和消息传递机制。

Activity的启动流程

我们可以将Activity划分为两种类型,根Activity和子Activity。

    根Activity:以快捷图标的形式显示在Launcher中,它的启动过程代表了一个Android应用程序的启动过程。
    子Activity:由根Activity或其他字Activity启动,他们有可能与启动他们的Activity运行在同一个进程中,也可能运行在不同的进程中。

因此,接下来我们将分析根Activity的启动流程,其他两种启动流程类似

    根Activity的启动流程
    子Activity在进程内的启动流程
    子Activity在新进程的启动流程

根Activity的启动流程

我们以Launcher组件启动新的应用程序的MainActivity为例。其过程大概分为以下6步:
(1) Launcher组件向ActivityManagerService发送一个启动MainActivity的进程间通信请求
(2) ActivityManagerService首先将要启动的MainActivity信息保存起来,然后再向Launcher发送一个进入终止状态的进程间通信请求
(3) Launcher组件进入终止状态后就会向ActivityManagerService发送一个已经进入终止状态的进程间通信请求,以便ActivityManagerService可以继续执行MainActivity的启动
(4) ActivityManagerService发现用于运行MainActivity的应用程序进程不存在,因此会先启动一个新的应用程序进程
(5) 新的应用程序进程启动后就会向ActivityManagerService发送一个启动完成的进程间通信请求,以便ActivityManagerService可以继续执行MainActivity的启动
(6) ActivityManagerService将第二步保存起来的MainActivity信息发送第四步创建的新的应用程序进程,以便将MainActivity启动起来

注:以ActivityManagerService为中心,我将此6步称为“三进三出”

接下来我们详细分析每一个步骤:

    Step1~Step5:
    Step1: Launcher.startActivitySafely
    Step2:Activity.startActivity
    Step3:Activity.startActivityForResult
    Step4:Instrumentation.execStartActivity
    Step5:ActivityManagerProxy.startActivity

Step1-Step5通知ActivityManagerService要启动新的Activity了(在Launcher所在进程执行)。

    Step6~Step12:
    step6:ActivityManagerService.startActivity
    step7:ActivityStack.startActivityMayWait
    step8:ActivityStack.startActivityLocked
    step9:ActivityStack.startActivityUncheckedLocked, ActivityStack.startActivityLocked
    step10:ActivityStack.resumeTopActivityLocked
    step11:ActivityStack.startPausingLocked

Step6-Step12通知Launcher程序应该pause Launcher的Activity了(在ActivityManagerService所在进程执行)

step8的ActivityStack.startActivityUncheckedLocked会检查有没有在AndroidManifest中注册即将要启动的Activity,如果没有注册,会返回一个ActivityStack.startActivityUncheckedLocked,然后Instrumentation.execStartActivity返回后回去检查这个值,然后抛出异常。

step9的ActivityStack.startActivityUncheckedLocked方法或去判断是否需要创建一个新的任务来启动Activity。在默认情况下,目标Activity与源Activity是运行在同一个任务中的,然而,如果源Activity将目标Activity的启动标志的FLAG_ACTIVITY_NEW_TASK设置为1,并且源Activity不需要知道目标Activity的运行结果,那么目标Activity就会运行在与源Activity不同的任务中。至于是否新建一个任务,则取决于目标Activity的taskAffinity属性,ActivityManagerService会先去查找taskAffinity属性所代表的任务是否已经存在,如果taskAffinity属性所代表的任务已经存在,则会将目标Activity置于该任务的栈顶,如果不存在,则先创建一个新的任务,并将目标Activity置于栈顶。

step10的ActivityStack.resumeTopActivityLocked方法会获取目前处于栈顶的正在激活的Activity,并通知Launcher应该pause掉这个Activity以便启动新的Activity。

    Step13~Step17:
    step13:ApplicationThread.schedulePauseActivity
    step14:ActivityThread.queueOrSendMessage
    step15:H.handleMessage
    step16:ActivityThread.handlePauseActivity
    step17:ActivityManagerProxy.activityPaused

step13-step17:pause Launcher的Activity,并通知ActivityManagerService已经pause结束了(在Launcher所在进程执行)

    Step18~Step23
    step18:ActivityManagerService.activityPaused
    step19:ActivityStack.activityPaused
    step20:ActivityStack.completePauseLocked
    step21:ActivityStack.resumeTopActivityLocked
    step22;ActivityStack.startSpecificActivityLocked
    step23:ActivityManagerService.startProcessLocked

step18-step23:创建一个新进程,调用ActivityThread.main方法(执行在ActivityManagerService进程)。这其中,ActivityManagerService会先检查目标Activity所需的应用进程是否存在,如果存在,就直接通知这个进程,在该进程中启动Activity,否则,会先调用Process.start创建一个新的应用程序进程。

注:这里就是与在同一个进程中启动Activity的区别之处

    Step24~Step25:
    step24:ActivityThread.main
    step25:ActivityManagerProxy.attachApplication

step24-step25:创建ActivityThread实例,初始化一些数据,进入Loop循环(执行在新创建的进程)

    Step26~Step29:
    step26:ActivityManagerService.attachApplication
    step27:ActivityManagerService.attachApplicationLocked
    step28:ActivityStack.realStartActivityLocked
    step29:ApplicationThreadProxy.scheduleLaunchActivity

step26-step29:处理新的应用进程发出的创建进程完成的通信请求,并通知新应用程序进程启动目标Activity组件(执行在ActivityManagerService进程)

    Step30~Step35:
    step30:ApplicationThread.scheduleLaunchActivity
    step31:ActivityThread.queueOrSendMessage
    step32:H.handleMessage
    step33:ActivityThread.handleLaunchActivity
    step34:ActivityThread.performLaunchActivity
    step35:MainActivity.onCreate

step30-step35:加载MainActivity类,调用onCreate声明周期方法(执行在新进程)
————————————————

原文链接:https://blog.youkuaiyun.com/weixin_36045176/article/details/80259942

`startActivity` 是 Android 开发中用于启动一个新 Activity 的核心方法,其全流程涉及多个组件和步骤,以下是详细总结: ### 1. 调用 `startActivity(Intent intent)` - 开发者在代码中调用 `startActivity(Intent)` 方法,传递一个 `Intent` 对象,该对象指定了要启动的目标 Activity(通过显式或隐式 Intent)。 - 如果未显式指定目标 Activity,系统会根据 `Intent` 的 `action`、`category` 和 `data` 等信息匹配合适的组件。 ### 2. 检查 `Intent` 的合法性 - 系统会检查 `Intent` 是否有效,例如是否包含目标组件信息(显式 Intent)或是否有足够的匹配条件(隐式 Intent)。 - 如果 `Intent` 无法匹配任何组件,会抛出 `ActivityNotFoundException`。 ### 3. 权限检查 - 系统会检查调用者是否具有启动目标 Activity 的权限(例如 `android.permission.START_ACTIVITIES_FROM_BACKGROUND` 或自定义权限)。 - 如果权限不足,会抛出 `SecurityException`。 ### 4. 任务栈(Task)管理 - 系统会根据 `Intent` 的 `FLAG_ACTIVITY_NEW_TASK`、`FLAG_ACTIVITY_SINGLE_TOP` 等标志位决定如何将目标 Activity 放入任务栈。 - 默认情况下,目标 Activity 会被压入当前任务栈的顶部。 - 如果设置了 `FLAG_ACTIVITY_NEW_TASK`,系统会尝试在新的任务栈中启动 Activity。 ### 5. 创建目标 Activity 的实例 - 系统通过 `Instrumentation` 类调用 `Activity.onCreate()` 方法创建目标 Activity 的实例。 - 在此过程中,系统会调用 `Activity` 的生命周期方法: - `onCreate()`:初始化 Activity。 - `onStart()`:Activity 变为可见但不可交互。 - `onResume()`:Activity 变为可见且可交互,进入运行状态。 ### 6. 动画与过渡效果 - 系统会根据主题(Theme)中的 `windowAnimationStyle` 或 `ActivityOptions` 配置启动动画(如淡入淡出、滑动等)。 - 如果使用了 `ActivityOptions`(例如共享元素过渡),系统会处理相应的过渡效果。 ### 7. 生命周期回调 - 当前 Activity(调用方)会触发 `onPause()` 方法。 - 如果目标 Activity 完全遮挡了当前 Activity,当前 Activity 还会触发 `onStop()` 方法。 - 当用户返回时,系统会调用目标 Activity 的 `onPause()` 和 `onStop()`,并恢复调用方 Activity 的 `onRestart()`、`onStart()` 和 `onResume()`。 ### 8. 返回栈(Back Stack)管理 - 系统将目标 Activity 压入返回栈,用户可以通过按下返回键返回到上一个 Activity。 - 返回栈遵循后进先出(LIFO)原则。 ### 示例代码 ```java // 显式 Intent 启动 Activity Intent intent = new Intent(CurrentActivity.this, TargetActivity.class); startActivity(intent); // 隐式 Intent 启动 Activity(需在 AndroidManifest.xml 中配置 Intent Filter) Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://example.com")); startActivity(intent); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值