首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Android】Activity的启动模式详解

【Android】Activity的启动模式详解

作者头像
三三是该溜子
发布2025-08-23 08:24:56
发布2025-08-23 08:24:56
22800
代码可运行
举报
文章被收录于专栏:该溜子的专栏该溜子的专栏
运行总次数:0
代码可运行

一:五种启动模式总结

启动模式

核心特性

实例创建规则

任务栈行为

典型应用场景

standard(默认)

最基础模式,无特殊限制

每次启动都会创建新实例,无论栈中是否已有该 Activity 实例

新实例进入当前任务栈,按启动顺序堆叠(先进后出)

新闻详情页、列表项详情等需要多次创建的页面

singleTop

避免栈顶重复实例,优化栈顶复用

若目标 Activity 已在任务栈顶部,则重用该实例并调用 onNewIntent();否则创建新实例

新实例进入当前任务栈;复用实例时保持栈结构不变(仅刷新栈顶)

搜索页面、通知栏点击跳转的页面(避免连续点击重复创建)

singleTask

确保整个任务栈中仅存在一个实例,且可被唤醒至栈顶

若栈中已存在该实例,将其移至栈顶并清除其上方所有实例;否则创建新实例并放入新任务栈

实例所在任务栈唯一,唤醒时通过调整栈结构保证实例在栈顶

银行应用主页、应用的核心功能页(如微信首页,确保全局唯一入口)

singleInstance

全局唯一实例,且独占一个独立任务栈,不与其他 Activity 共享

整个系统中仅存在一个实例,无论从哪个应用启动,均复用该实例

实例位于独立任务栈中,其他任何 Activity 都无法进入此栈

视频播放页、闹钟页面(需独立于其他任务,支持多任务切换时不中断)

singleInstancePerTask(Android 12+)

每个任务栈中仅一个实例,不同任务栈可存在多个实例,适配多窗口场景

同一任务栈中若已有实例则复用;新任务栈启动时会创建新实例

每个实例独占所在任务栈,但不同任务栈可包含该 Activity 的不同实例

多窗口模式下的工具类页面(如文档编辑器,每个窗口任务可独立拥有一个实例)

二:准备工作

准备LaunchMode1Activity和LaunchMode2Activity两个类和Standard,按钮和TextView都有相应的监听器,会触发一些事件

代码语言:javascript
代码运行次数:0
运行
复制
public class LaunchMode1Activity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_launch_mode1);

        findViewById(R.id.btn_launch1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //跳转到自己的页面
//                Intent intent = new Intent(LaunchMode1Activity.this, LaunchMode2Activity.class);
                Intent intent = new Intent(LaunchMode1Activity.this, LaunchMode2Activity.class);

                startActivity(intent);
            }
        });

        findViewById(R.id.tv_launch1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //跳转到自己的页面
                Intent intent = new Intent(LaunchMode1Activity.this, LaunchMode2Activity.class);
                startActivity(intent);
            }
        });

    }
}
代码语言:javascript
代码运行次数:0
运行
复制
public class LaunchMode2Activity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_launch_mode2);

        findViewById(R.id.btn_launch2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //跳转到自己的页面
                Intent intent = new Intent(LaunchMode2Activity.this, StandardActivity.class);
                startActivity(intent);
            }
        });


        findViewById(R.id.tv_launch2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //跳转到自己的页面
                Intent intent = new Intent(LaunchMode2Activity.this, StandardActivity.class);
                startActivity(intent);
            }
        });

    }
}
代码语言:javascript
代码运行次数:0
运行
复制
public class StandardActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_standard);

        findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //跳转到自己的页面
                Intent intent = new Intent(StandardActivity.this, StandardActivity.class);
                startActivity(intent);
            }
        });

        findViewById(R.id.tv_start).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //跳转到自己的页面
//                Intent intent = new Intent(StandardActivity.this, LaunchMode1Activity.class);
                Intent intent = new Intent(StandardActivity.this, StandardActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
                startActivity(intent);
            }
        });

    }
}

0:lanchMode

在清单中设置它,表示启动模式

1:Standard

标准模式,就是栈的基本特点,Activity先进先出,如果要创建的Activity在栈中已经存在了,也会在创建一个新的Activity扔到栈里面放到栈顶。

2:singTop

singleTop:如果要启动的 Activity 已经位于任务栈的顶部,则不会创建新实例,而是调用其 onNewIntent() 方法;如果不在栈顶,则会创建新实例栈顶模式

代码语言:javascript
代码运行次数:0
运行
复制
public class StandardActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_standard);

        findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //跳转到自己的页面
                Intent intent = new Intent(StandardActivity.this, StandardActivity.class);
                startActivity(intent);
            }
        });

    }
}
(1)在栈顶

点击按钮launch1,并不会发生页面跳转(不会创建新StandardActivity实例,因为栈中只存在StandardActivity实例并且它在栈顶)

(2)不在栈顶

second跳转到StandardActivity,尽管栈中已经存在StandardActivity,但它并不在栈顶,所以重新创建一个新的实例,放置栈顶

3:singleTask

单任务模式,需要略改上述代码,就是跳转页面的逻辑那一块

特点:当启动 Activity 时,系统会检查所有任务栈和实例

  • 若存在:将该任务栈整体移到前台,并清空该实例上方的所有 Activity(使其成为栈顶),同时调用其 onNewIntent() 方法。
  • 若不存在:创建新任务栈和该 Activity 的实例。

举例说明:假设任务栈结构为 [A, B, C, D](A 是栈底,D 是栈顶),其中 C 是 singleTask 模式

当再次启动 C 时:

  • 系统会销毁 C 上方的所有 Activity(即 D)
  • 最终栈结构变为 [A, B, C](C 成为新的栈顶)
  • C 实例被复用,并调用其 onNewIntent() 方法

这种模式就特别适合app的首页,短视频啊app,点开好多个视频,想返回首页

4:singleInstance

单实例模式

singleTask 的强化版,该 Activity 会独占一个全新的任务栈,且整个系统中只有一个实例;

若已存在实例时,系统会复用已有的实例

核心特性:独享任务栈、全局单实例、重复启动时只调至前台

使用场景:闹钟,独立的任务栈中去播放视频

  • 示例
    • 从应用 A 启动 singleInstance 的 Activity X,会创建任务栈 [X]
    • 从应用 B 再次启动 X 时,直接复用已有的 [X] 任务栈和实例,不会创建新的。

动画就像在启动一个新的页面一样

两者的关键区别和总结

特性

singleTask

singleInstance

任务栈

可与其他 Activity 共享同一个任务栈

独占一个任务栈,不允许其他 Activity 进入

实例数量

整个系统中唯一实例

整个系统中唯一实例

启动其他 Activity

其他 Activity 会进入当前任务栈

其他 Activity 会进入新的任务栈

  • singleTask 适合作为应用的核心页面,确保唯一实例并管理任务栈的层级。
  • singleInstance 适合完全独立的功能页面,与其他 Activity 严格隔离。

5:singleInstancePerTask

singleInstancesingleInstancePerTask 的核心差异就在于实例唯一性的范围

singleInstance是全局仅有一个实例;singleInstancePerTask可以在不同的任务栈中存在相同的实例

举例:

  • 若 Activity Z 是 singleInstance,则无论你从「微信任务栈」「浏览器任务栈」还是「相册任务栈」启动 Z,始终只有一个 Z 实例在运行。
  • 若 Activity Z 是 singleInstancePerTask,从「微信任务栈」启动 Z 会创建 Z1 实例(独占一个任务栈),从「浏览器任务栈」启动 Z 会创建 Z2 实例(另一个独占任务栈),Z1 和 Z2 是两个完全独立的实例。

场景需要:在不同任务中保持独立状态——多文档编辑

三:Java控制启动模式

设置单独的启动标志

1:四种Flag标志总结

Intent Flag

对应 / 关联的 launchMode

核心行为描述

典型应用场景

无特殊 Flag(默认)

standard

每次启动都创建新实例,放入当前任务栈顶。

大多数普通页面(如列表项详情、表单页)

FLAG_ACTIVITY_SINGLE_TOP

singleTop

若目标 Activity 位于栈顶,则复用该实例(调用 onNewIntent),否则创建新实例。

避免重复启动栈顶 Activity(如通知栏点击进入已在栈顶的详情页)

FLAG_ACTIVITY_CLEAR_TOP

与 singleTask 关联

若目标 Activity 已在栈中(无论位置),销毁其上方所有 Activity 并复用该实例(调用 onNewIntent)。

需要返回某个页面并清除中间页面(如从详情页返回首页并清除所有中间页)

FLAG_ACTIVITY_NEW_TASK

与 singleTask/singleInstance 关联

为目标 Activity 创建新任务栈(若不存在),作为栈根。

从后台服务启动 Activity、跨应用启动 Activity(如从浏览器打开第三方应用页面)

FLAG_ACTIVITY_REORDER_TO_FRONT

无直接对应 launchMode

将栈中已有的目标 Activity 移动到栈顶,不销毁其他 Activity。

需将历史页面调至前台但保留栈结构(如多标签页切换、返回最近浏览的页面)

(系统特殊处理)

singleInstance

实例独占一个任务栈,全局唯一,跨任务复用同一实例。

系统级全局页面(如来电界面、全局搜索)

(系统特殊处理)

singleInstancePerTask

每个任务栈中仅一个实例,不同任务栈可有独立实例,各实例独占任务栈(API 31+)。

多任务独立页面(如每个文档任务的专属编辑器)

2:用法

代码语言:javascript
代码运行次数:0
运行
复制
		findViewById(R.id.tv_start).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //跳转到自己的页面
//                Intent intent = new Intent(StandardActivity.this, LaunchMode1Activity.class);
                Intent intent = new Intent(StandardActivity.this, StandardActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
                startActivity(intent);
            }
        });
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-08-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一:五种启动模式总结
  • 二:准备工作
    • 0:lanchMode
    • 1:Standard
    • 2:singTop
      • (1)在栈顶
      • (2)不在栈顶
    • 3:singleTask
    • 4:singleInstance
    • 两者的关键区别和总结
    • 5:singleInstancePerTask
  • 三:Java控制启动模式
    • 1:四种Flag标志总结
    • 2:用法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档