【Android】Activity的启动模式详解

在这里插入图片描述

三三要成为安卓糕手

一:五种启动模式总结

启动模式核心特性实例创建规则任务栈行为典型应用场景
standard(默认)最基础模式,无特殊限制每次启动都会创建新实例,无论栈中是否已有该 Activity 实例新实例进入当前任务栈,按启动顺序堆叠(先进后出)新闻详情页、列表项详情等需要多次创建的页面
singleTop避免栈顶重复实例,优化栈顶复用若目标 Activity 已在任务栈顶部,则重用该实例并调用 onNewIntent();否则创建新实例新实例进入当前任务栈;复用实例时保持栈结构不变(仅刷新栈顶)搜索页面、通知栏点击跳转的页面(避免连续点击重复创建)
singleTask确保整个任务栈中仅存在一个实例,且可被唤醒至栈顶若栈中已存在该实例,将其移至栈顶并清除其上方所有实例;否则创建新实例并放入新任务栈实例所在任务栈唯一,唤醒时通过调整栈结构保证实例在栈顶银行应用主页、应用的核心功能页(如微信首页,确保全局唯一入口)
singleInstance全局唯一实例,且独占一个独立任务栈,不与其他 Activity 共享整个系统中仅存在一个实例,无论从哪个应用启动,均复用该实例实例位于独立任务栈中,其他任何 Activity 都无法进入此栈视频播放页、闹钟页面(需独立于其他任务,支持多任务切换时不中断)
singleInstancePerTask(Android 12+)每个任务栈中仅一个实例,不同任务栈可存在多个实例,适配多窗口场景同一任务栈中若已有实例则复用;新任务栈启动时会创建新实例每个实例独占所在任务栈,但不同任务栈可包含该 Activity 的不同实例多窗口模式下的工具类页面(如文档编辑器,每个窗口任务可独立拥有一个实例)

二:准备工作

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

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);
            }
        });

    }
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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);
            }
        });

    }
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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() 方法;如果不在栈顶,则会创建新实例栈顶模式


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] 任务栈和实例,不会创建新的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
动画就像在启动一个新的页面一样

两者的关键区别和总结

特性singleTasksingleInstance
任务栈可与其他 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_TOPsingleTop若目标 Activity 位于栈顶,则复用该实例(调用 onNewIntent),否则创建新实例。避免重复启动栈顶 Activity(如通知栏点击进入已在栈顶的详情页)
FLAG_ACTIVITY_CLEAR_TOPsingleTask 关联若目标 Activity 已在栈中(无论位置),销毁其上方所有 Activity 并复用该实例(调用 onNewIntent)。需要返回某个页面并清除中间页面(如从详情页返回首页并清除所有中间页)
FLAG_ACTIVITY_NEW_TASKsingleTask/singleInstance 关联为目标 Activity 创建新任务栈(若不存在),作为栈根。从后台服务启动 Activity、跨应用启动 Activity(如从浏览器打开第三方应用页面)
FLAG_ACTIVITY_REORDER_TO_FRONT无直接对应 launchMode将栈中已有的目标 Activity 移动到栈顶,不销毁其他 Activity。需将历史页面调至前台但保留栈结构(如多标签页切换、返回最近浏览的页面)
(系统特殊处理)singleInstance实例独占一个任务栈,全局唯一,跨任务复用同一实例。系统级全局页面(如来电界面、全局搜索)
(系统特殊处理)singleInstancePerTask每个任务栈中仅一个实例,不同任务栈可有独立实例,各实例独占任务栈(API 31+)。多任务独立页面(如每个文档任务的专属编辑器)

2:用法

		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);
            }
        });

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值