Activity启动原理、启动模式

在Android开发中,Activity的启动模式决定了Activity的启动和运行方式。
Android提供了四种基本的启动模式,分别是:standard、singleTop、singleTask和singleInstance。
每种模式都有其特定的应用场景和行为特性。

一、Activity的四种启动模式

  1. standard(标准模式)

    • 行为:默认的启动模式,每次启动Activity时都会创建一个新的实例,并将其放入任务栈中。所以,任务栈中可能同时存在该Activity的多个实例。
    • 应用场景:每次打开都是新内容或新页面。比如新闻内容列表,每次打开都是新页面。
  2. singleTop(单顶模式,or栈顶复用模式)

    • 行为:如果任务栈的栈顶已经是该Activity的实例,则不会创建新的实例,而是直接复用栈顶的Activity实例。如果栈顶不是该Activity的实例,则会创建新的实例并放入栈中。
    • 应用场景:适用于那些不需要多个实例的Activity,比如通知栏消息点击打开应用
  3. singleTask(单任务模式,or栈内复用模式)

    • 行为:如果任务栈中已经存在该Activity的实例,则不会创建新的实例,而是将任务栈中该实例以上的所有Activity实例都移除,让该实例位于栈顶。如果任务栈中不存在该Activity的实例,则创建新的实例。
    • 应用场景:适用于作为应用程序入口的Activity,如APP的主页或主界面!!!确保无论从哪里进入应用,都回到主页面而不是在主页面上方叠加新的页面。
  4. singleInstance(单实例模式)

    • 行为:该模式下的Activity会单独位于一个任务栈中。无论从哪里启动该Activity,都会重用这个实例,并且该Activity会单独占据一个任务栈。
    • 生命周期:走(onPause) -> onNewIntent() -> onResume
    • 应用场景
      适用于与其他完全隔离的Activity,如来电显示页面;
      适用于那些需要全局唯一实例的Activity,比如系统级的服务Activity或者需要全局共享数据的Activity。
主Activity一般用哪种启动模式

对于主Activity(即应用的首页或主界面),一般推荐使用singleTopsingleTask启动模式

  • 使用singleTop模式:如果主Activity已经位于任务栈的栈顶,再次启动它时不会创建新的实例,而是直接复用现有的实例。
    这可以避免不必要的Activity创建和销毁,提高应用的性能和用户体验。
  • 使用singleTask模式:如果主Activity在任务栈中存在,无论它位于栈的哪个位置,都会将它之上的所有Activity实例移除,
    并将其置于栈顶。这可以保证用户无论通过哪种方式回到应用,都会直接看到主Activity,并且
    主Activity上方不会有其他Activity遮挡。

最终选择哪种模式,需要根据应用的具体需求和用户体验来决定。如果应用结构相对简单,用户行为也比较单一,使用singleTop模式可能就足够了。如果应用结构复杂,需要处理多种用户场景和跳转逻辑,那么使用singleTask模式可能更加合适。

5、使用方式

(1)在AndroidManifest.xml,指定android:launchMode=“singleInstance”;

(2)通过Intent设置标志位,addFlags(NEW_TASK、CLEAR_TOP、SINGLE_TOP)

二、生命周期

1、 onCreate(Bundle):初始化基础组件和视图;调用setContentView()设置布局。接收Bundle参数可恢复之前的数据。
在调用此方法之前,activity实例创建完成,并调用attach赋值PhoneWindow、ContextImpl等属性

2、 onStart():注册View点击监听,观察者对象等

3、 onResume():准备好交互。启动或恢复一些动态对象,因为view绘制就在resume之后

4、 onPause():失去焦点时调用,暂停动画或视频等,比如被非全屏的弹窗覆盖

5、 onStop():注销所有观察者和监听者,释放onStart()中分配的所有资源,如被全屏弹窗或activity覆盖

6、 onDestroy():activity被系统杀死或调用finish方法后移除对象等

三、启动原理

1、根Activity(Launcher Activity)启动过程

在Android系统中,Activity Manager Service (AMS) 负责管理应用程序的生命周期、进程调度、任务栈管理以及系统服务控制等核心功能。当启动一个根Activity(Launcher Activity)时,AMS及其核心类(如ActivityStack、ActivityRecord、ProcessRecord、TaskRecord)通过一系列复杂的交互和流程来确保Activity能够正确创建和显示。以下是这些核心类在Activity启动过程中的具体作用,结合源码进行说明:

1.1 用户操作与请求AMS
  • 用户操作:用户点击桌面上的应用图标。
  • 请求AMS:Launcher应用捕获到这个点击事件,并通过startActivity()方法向AMS发送一个启动新Activity的请求。这个请求包含了Intent、Activity的类名等信息。
1.2 进程检查与创建
  • AMS检查进程:AMS接收到启动请求后,首先会检查目标Activity所属的应用进程是否已经存在。这一检查通常是通过查询系统中已有的ProcessRecord列表来完成的。ProcessRecord包含了进程的基本信息,如包名、进程名、进程ID等。
  • 创建新进程:如果目标进程不存在,AMS会请求Zygote进程通过fork()方法创建一个新的应用进程。Zygote是所有应用进程的父进程,它包含了Android运行时的环境。新进程创建后,会启动一个主线程(ActivityThread),并创建一个ApplicationThread作为Binder服务端,用于与AMS进行通信。
1.3 ActivityRecord与TaskRecord的创建
  • ActivityRecord的创建:在AMS中,每个启动的Activity都会对应一个ActivityRecord实例。ActivityRecord包含了Activity的详细信息,如Intent、ActivityInfo、进程ID等。当AMS决定启动一个新的Activity时,它会创建一个新的ActivityRecord,并将其添加到相应的ActivityStack中。
  • TaskRecord的创建:TaskRecord是AMS中用于管理一组相关Activity的数据结构。每个TaskRecord代表一个任务栈,可以包含多个ActivityRecord。当启动一个新的Activity时,AMS会根据Intent中的信息(如FLAG_ACTIVITY_NEW_TASK)来决定是否需要创建一个新的TaskRecord,或者将Activity添加到已有的TaskRecord中。
1.4 Activity的创建与显示
  • ActivityThread的处理:在主线程(ActivityThread)中,当ApplicationThread接收到AMS的启动Activity请求时,它会调用performLaunchActivity()方法来处理这个请求。这个方法负责加载Activity的类,创建其实例,并调用onCreate()onStart()onResume()等生命周期方法,从而完成Activity的创建和显示。
  • ActivityStack与TaskRecord的更新:随着Activity的创建和显示,AMS中的ActivityStack和TaskRecord也会相应地进行更新。ActivityRecord会被添加到ActivityStack中,以反映当前系统中Activity的状态。同时,TaskRecord也会更新其内部的Activity列表,以维护Activity的启动顺序和切换顺序。

以下是一个简化的伪代码Java示例,描述了根Activity(Launcher Activity)的启动过程。请注意,由于这是伪代码,它不会直接编译或运行,但它能够清晰地表达整个启动流程的逻辑。

// 伪代码示例:根Activity启动过程

// 假设这是Launcher应用中的某个部分,用户点击了桌面图标
public class LauncherActivity {

    // 模拟用户点击桌面图标的行为
    public void onIconClicked() {
        // 捕获到点击动作,准备启动新的Activity
        Intent intent = new Intent(this, RootActivity.class);
        startActivity(intent);
    }

    // 假设这是LauncherActivity中的startActivity方法,实际中由系统框架实现
    private void startActivity(Intent intent) {
        // 简化处理,直接模拟向AMS发送请求
        // 在实际Android系统中,这部分由系统框架处理,包括IPC通信等
        sendStartActivityRequestToAMS(intent);
    }

    // 模拟向AMS发送启动Activity的请求
    private void sendStartActivityRequestToAMS(Intent intent) {
        // 这里只是模拟,实际中AMS会进行一系列的检查和准备
        // 假设AMS检查并决定需要启动一个新的进程

        // 假设这是AMS的一部分,用于处理新进程的创建和Activity的启动
        ActivityManagerService ams = new ActivityManagerService();
        ams.handleStartActivity(intent);
    }

    // 假设的ActivityManagerService类,用于处理Activity的启动
    class ActivityManagerService {

        // 处理启动Activity的请求
        public void handleStartActivity(Intent intent) {
            // 检查目标Activity所属的应用进程是否已存在
            boolean processExists = checkProcessExists(intent.getComponent());

            if (!processExists) {
                // 如果不存在,请求Zygote进程fork出一个新的应用进程
                forkNewProcessForApplication(intent.getComponent());
            }

            // 向新进程或已存在的进程发送启动Activity的请求
            sendStartActivityRequestToApplicationThread(intent);
        }

        // 检查进程是否存在(伪代码)
        private boolean checkProcessExists(ComponentName componentName) {
            // 简化处理,直接返回false表示进程不存在
            return false;
        }

        // 请求Zygote进程fork新进程(伪代码)
        private void forkNewProcessForApplication(ComponentName componentName) {
            // 简化处理,实际中会涉及Zygote进程和IPC通信
            System.out.println("Forking new process for " + componentName.getClassName());
        }

        // 向ApplicationThread发送启动Activity的请求(伪代码)
        private void sendStartActivityRequestToApplicationThread(Intent intent) {
            // 简化处理,实际中会通过IPC机制发送请求
            // 假设这是新进程中的ApplicationThread
            ApplicationThread applicationThread = new ApplicationThread();
            applicationThread.scheduleLaunchActivity(intent);
        }

        // 假设的ApplicationThread类,用于接收AMS的请求并启动Activity
        class ApplicationThread {

            // 调度启动Activity
            public void scheduleLaunchActivity(Intent intent) {
                // 简化处理,直接调用ActivityThread的方法
                ActivityThread activityThread = new ActivityThread();
                activityThread.handleLaunchActivity(intent);
            }
        }

        // 假设的ActivityThread类,负责Activity的创建和生命周期管理
        class ActivityThread {

            // 处理Activity的启动
            public void handleLaunchActivity(Intent intent) {
                // 简化处理,直接调用Activity的onCreate等方法
                RootActivity activity = new RootActivity();
                activity.onCreate(intent.getExtras());
                activity.onStart();
                activity.onResume();

                // 假设这里完成了Activity的显示
                System.out.println("RootActivity is launched and displayed");
            }
        }
    }
}

// 假设的RootActivity类
class RootActivity {

    // onCreate方法
    public void onCreate(Bundle savedInstanceState) {
        // 初始化操作
        System.out.println("RootActivity onCreate()");
    }

    // onStart方法
    public void onStart() {
        System.out.println("RootActivity onStart()");
    }

    // onResume方法
    public void onResume() {
        System.out.println("RootActivity onResume()");
    }
}

请注意,这个伪代码示例是为了说明流程而简化的,它并不符合Android系统的实际实现细节。在Android系统中,Activity的启动和管理是由系统框架(如ActivityManagerService、ActivityThread等)通过复杂的IPC机制和系统服务来完成的。

2、普通Activity启动过程

在Android系统中,普通Activity的启动过程也涉及到了AMS(Activity Manager Service)及其核心类(ActivityStack、ActivityRecord、ProcessRecord、TaskRecord)的复杂交互。下面,我将根据源码的概念来详细展开这一过程:

2.1 内部请求

当应用进程中的某个组件(如Activity、Service或BroadcastReceiver)调用startActivity()方法时,它会构建一个包含目标Activity信息的Intent对象,并通过Binder IPC机制将启动请求发送给AMS。

2.2 AMS管理
2.2.1 接收请求

AMS(ActivityManagerService)的某个Binder接口(如IActivityManager)会接收到这个启动请求。然后,它会对请求进行一系列的检查和准备,包括但不限于:

  • 解析Intent:确定Intent中指定的Activity信息,包括类名、包名等。
  • 安全检查:验证发起请求的应用是否有权限启动目标Activity。
  • 解析和匹配Activity配置:根据Intent中的信息(如Action、Category、Data等)和目标Activity的<intent-filter>进行匹配。
2.2.2 进程管理

接下来,AMS会检查目标Activity所属的应用进程是否已经存在:

  • 如果进程存在:AMS会直接将启动请求发送给该进程中的ActivityThread,请求它创建并启动Activity。
  • 如果进程不存在:AMS会执行以下步骤:
    • 通过Zygote进程创建一个新的应用进程。Zygote是所有应用进程的父进程,它包含了Android运行时的环境。
    • 在新进程中启动ActivityThread,并初始化一个新的ApplicationThread实例(这个实例是IApplicationThread接口的实现,用于与AMS进行IPC通信)。
    • AMS通过Binder IPC机制将启动请求发送给新进程中的ApplicationThread
2.2.3. Activity创建与显示

目标进程中的ActivityThread接收到AMS发送的启动请求后,会执行以下步骤来创建和显示Activity:

  • 解析请求:解析从AMS接收到的启动请求,获取Intent、Activity的类名等信息。
  • 加载Activity类:使用类加载器加载Activity的类文件。
  • 创建Activity实例:调用Activity的构造函数创建其实例。
  • 初始化Activity:调用Activity的onCreate()onStart()onResume()等生命周期方法,进行必要的初始化工作。
  • 添加Activity到Task和Stack:在AMS中,ActivityRecord会被添加到相应的TaskRecord中,而TaskRecord则会被添加到ActivityStack中。这个过程是由AMS在发送启动请求时和Activity创建后通过一系列的回调和IPC通信来完成的。
  • 显示Activity:完成上述步骤后,Activity的UI就会显示在屏幕上。
2.2.4 注意
  • 在Android源代码中,IApplicationThread接口是一个Binder接口,它定义了AMS与目标进程中的ApplicationThread进行IPC通信的方法。然而,在实际的IPC通信过程中,可能会涉及到更底层的Binder机制,如BinderProxyBinderNative等类的使用。
  • ApplicationThreadIApplicationThread接口的一个实现类,它位于目标应用进程中,并通过Binder机制与AMS进行通信。但是,在Android的源码中,ApplicationThread可能不是直接作为IApplicationThread的实现类出现,而是通过一系列的代理和封装来实现IPC通信的。
  • 实际上,在Activity的启动过程中,还会涉及到许多其他的类和接口,如InstrumentationActivityManagerService.ActivityStarter等,它们都在幕后默默地工作,以确保Activity能够顺利地创建和显示。

四、 ActivityThread和ApplicationThread:

在Android系统中,ActivityThreadApplicationThread扮演着至关重要的角色,它们共同协作以确保应用程序能够顺利运行并处理各种UI事件和系统服务请求。以下是关于这两个类的详细解析:

1、ActivityThread

定义与功能

  • 定义ActivityThread是Android应用程序的主线程,也称为UI线程。它是应用程序的入口点,负责处理所有的UI操作、事件处理以及启动和管理应用程序中的组件(如Activity、Service等)。
  • 功能
    1. UI更新:处理所有的用户界面更新,确保界面流畅且响应迅速。
    2. 事件处理:接收并处理用户输入和系统事件,如触摸事件、按键事件等。
    3. 启动Activity:管理Activity的生命周期,包括创建、启动、暂停、恢复和销毁等过程。
    4. 消息循环:通过Looper和Handler机制管理消息队列,处理来自系统和应用程序的各种消息。

工作流程

  • 当Android系统启动一个应用程序时,会为该应用程序创建一个新的进程,并在该进程中实例化一个ActivityThread对象。
  • ActivityThreadmain方法作为应用程序的入口点,会初始化Looper和消息队列,然后进入消息循环。
  • 在消息循环中,ActivityThread会处理各种消息,包括来自AMS的生命周期事件请求和用户输入事件等。
2、ApplicationThread

定义与功能

  • 定义ApplicationThreadActivityThread的一个内部类,实现了IApplicationThread接口,该接口是一个Binder接口,用于跨进程通信(IPC)。
  • 功能
    1. IPC通信:作为系统服务(如AMS)和应用程序进程之间的通信桥梁,处理来自AMS的请求,并将请求转发给ActivityThread进行处理。
    2. 生命周期管理:通过IPC机制接收AMS发送的生命周期事件请求,并转发给ActivityThread以执行相应的生命周期方法。

工作流程

  • 当AMS需要管理应用程序的组件(如启动、停止Activity)时,它会通过Binder机制发送请求给ApplicationThread
  • ApplicationThread接收到请求后,会将其转换为ActivityThread能够理解的格式,并调用ActivityThread中的相应方法进行处理。
  • ActivityThread根据请求执行相应的操作,如创建和启动Activity,并更新其生命周期状态。
3、总结

ActivityThreadApplicationThread在Android应用程序的运行过程中紧密协作,共同负责UI更新、事件处理、组件生命周期管理以及系统服务请求的处理。ActivityThread作为应用程序的主线程,负责处理所有的UI操作和事件;而ApplicationThread则作为IPC通信的桥梁,将系统服务的请求转发给ActivityThread进行处理。这种设计确保了Android应用程序能够高效地运行,并与其他系统服务进行无缝交互。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

望佑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值