Android基础 - 重温Activity的启动模式

我们知道一个应用可能存在多个Activity,在一个Activity除了可以启动本应用的另一个Activity,还可能是其他应用的Activity,比如我们常用的分享朋友圈、拍照等等功能,就是典型的跨应用的交互,那么在Android中是如何管理这些Activity的呢?接下来先了解下Activity的任务栈

任务栈(Task)

任务栈的定义

官网文档的定义

任务是指在执行特定作业时与用户交互的一系列 Activity。 这些 Activity 按照各自的打开顺序排列在堆栈(即返回栈)中。

简而言之,是管理Activity的一种集合,其结构是“后进先出”特点,启动一个Activity并会添加到集合末尾(入栈),按back键并会从集合末尾移除(出栈)。
这里写图片描述

任务的起点大多数是从手机桌面屏幕为开始。

  • 若任务存在,当点击桌面应用图标并会触发任务的响应,显示到前台。
  • 若任务不存在(或近期未使用),则会新创建一个任务栈,并将主Activity作为堆栈中根Activity打开。

任务栈的使用

默认情况下任务栈的名称是应用的包名,如果要为某个Activity指定一个新的任务栈,则需使用taskAffinity属性,在AndroidMainfest文件中设置,如下:

<activity
            android:name=".SingleTaskActivity"
            android:launchMode="singleTask"
            android:taskAffinity="com.hzw.singleTask"/>

查看当前系统的任务栈

1、在手机中点击多窗口任务键即可查看

这里写图片描述
从上面的图看出可以同一个App,可以有多个任务栈(据说微信小程序页面是独立一个任务栈)。
关于同个APP多个任务的实现可以参考同一个app不同activity显示多任务(仿微信小程序切换效果)

2、使用命令方式查看adb shell dumpsys activity

这里写图片描述
使用命令行的方式查看,同样可知同一个APP可以包含多个任务栈(Task)。

注意:
使用命令行查看任务栈信息,输出的消息会比较多,我们选择性地看,比如查看Running activites(most recent first)这一块即可。

四种启动模式

1、standard:标准模式,也是默认的

  • 重复创建会创建多个实例
  • 使用该模式,谁启动该Activity,新Activity就会运行在启动者所在的栈中
  • 使用非Activity类型的Context(如ApplicationContext)启动该模式的Activity,会报错。

这里写图片描述

2、singleTop:栈顶复用模式

  • 如果新Activity已位于任务栈栈顶,重复启动则不会创建新实例,不会调用onCreate、onStart方法,会直接回调onNewIntent方法。
  • 如果新Activity不在栈中或者位于栈内,此情况和标准模式一样创建多个实例。
    这里写图片描述
    这里写图片描述

使用场景:比如消息推送,当接受新消息显示在通知栏,此时点击消息会跳到指定的Activity页面,如果指定页面已存在栈顶中,则无需再次创建该Activity页面实例,避免了资源浪费,同时交互体验上得到优化。

3、singleTask:栈内复用模式

  • 只要 Activity 在一个栈中有实例,多次启动此 Activity 都不会创建实例,也是直接调用 onNewIntent方法
  • 启动 singleTask 的 Activity 时,系统会先找有没有想要的任务栈,没有就新建个任务栈。
  • 栈内有实例,就会把该 Activity 调到栈顶,具有 clearTop效果,会把该Activity上面所有页面清除,从栈内移出

这里写图片描述
新启动的SingleTaskActivity 指定了任务栈,默认情况下不存在该栈名,于是新建了一个“com.hzw.singleTask”的名称任务栈。
使用场景:常用分享微信及朋友圈功能,就是一个典型的例子,在其他APP分享到微信,无论微信当前栈顶是那个Activity,分享成功后,只要点击留在微信,就会跳到微信主页。此模式一般是用于MainActivity,因为回到首页需清除上面所有的页面。

4、singleInstance:单实例模式

  • 加强版的singleTask模式。
  • 使用该模式,则会单独创建一个任务栈来存放新Activity。

这里写图片描述

标志位Flags

启动模式的两种方法

1、通过AndroidMainfest指定启动模式,如下:

<activity
            android:name=".SingleTaskActivity"
            android:launchMode="singleTask"/>

2、通过Intent中设置标志位启动,如下:

Intent intent = new Intent(this, SingleTopActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);

两者的区别:

  • 优先级不同,第二种比第一种的优先级高,如同时存在,则以第二种为准。
  • 使用范围有不同,比如第一种无法为Activity设置FLAG_ACTIVITY_CLEAR_TOP标志,而第二种则无法设置singleInstance模式。

常用标志位

FLAG_ACTIVITY_NEW_TASK

  • 与 “singleTask”launchMode 值相同的行为

FLAG_ACTIVITY_SINGLE_TOP

  • 与 “singleTop”launchMode 值相同的行为

FLAG_ACTIVITY_CLEAR_TOP

  • 如果正在启动的 Activity 已在当前任务中运行,则会销毁当前任务顶部的所有 Activity,并通过 onNewIntent() 将此 Intent 传递给 Activity 已恢复的实例(现在位于顶部),而不是启动该 Activity 的新实例。
  • 在launchMode 属性没有值。
  • 一般需要和FLAG_ACTIVITY_NEW_TASK配合使用。

FALG_ACTIVITY_EXCLUDE_FROM_RESENTS

  • 具有此标记的Activity是不会出现在历史Activity的列表中。

感谢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值