Android-Activity的启动模式

本文深入解析了Android中Activity的不同启动模式,包括standard、singleTop、singleTask和singleInstance的特点及应用场景,并介绍了如何通过配置文件和代码来指定Activity的启动模式。

为什么Activity需要启动模式呢?在默认情况下,当我们多次启动一个Activity时,系统会创建多个实例并把它们一一放入任务栈中,当我单机Back键时,这些Activity一一回退。任务栈是一个栈,所以是一种后进先出的数据结构。
知道了任务栈的原理,我们就知道为什么需要启动模式了。不然多次启动一个Activity,就创建多个实例,这不是很傻吗?确实很少,Activtiy设计者不可能没有考虑到这个问题,这就是启动模式的意义。

Activity的启动模式(LaunchMode)

standard(标准模式)

标准模式,也就是系统的默认模式。每次启动一个Activity都会重新创建一个新的实例,不管它是否已经存在。在这种模式下,谁启动了这个Activity,那么这个Activity就运行在启动他的那个Activity所在的任务栈中。
当我们用ApplicationContext去启动一个standard模式的Activity时,就会报错,因为ApplicationContext没有任务栈啊,解决这个问题的办法就是为待启动的Activity指定FLAG_ACTIVITY_NEW_TASK标志位,这样启动的时候就会为它创建一个新的任务栈,这时候启动Activity其实是singleTask。

Intent intent = new Intent(getApplicationContext(),LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

singleTop(栈顶复用模式)

在这种模式下,如果新的Activity已经位于栈顶了,那么此Activity不会被重新创建,同时它的onNewIntent方法会被回调,通过此方法的参数我们可以去除当前请求的信息。需要注意的是,这个Activity的onCreate和onStart不会被回调。如果新的Activity已经存在,但是不是位于栈顶,那么还是会重新创建一个实例。

singleTask(站内复用模式)

这是一种单例模式,在这种模式下,只要Activity在这个栈内存在,那么多次启动这个Activity都不会重新创建实例,和singleTop一样,也会回调onNewIntent方法。
但是要记住任务栈是栈结构的。所以要想把栈中的元素切换到栈顶,需要把上面的所有元素全部出栈。也就是在这个Activity之上的Activity都会出栈。

singleInstance(但实例模式)

这是一个加强的singleTask模式,它除了具有singleTask模式的所有特性之外,还加强了一点,那就是具有此模式的Activity只能单独的位于一个任务栈中。

任务栈

需要从一个参数说起TaskAffinity。

<activity
            android:taskAffinity="login"
            android:name=".activity.LoginActivity"
            android:label="@string/title_activity_login" />

这个参数标识了一个Activity所需要的任务栈的名字,默认情况下,所需任务栈的名字和包名一样。当然我们可以指定这个参数,必须不能喝包名一样,不然等于没指定。
TaskAffinity主要和singleTask,allowTaskReparenting属性配对使用。
1,当TaskAffinity和singleTask配对使用时,Activity的任务栈的名字就是TaskAffinity。
2,当TaskAffinity和allowTaskReparenting配对使用时,会产生复杂的效果。当一个应用A启动了应用B的一个Activity后,如果这个Activity的allowTaskReparenting为true,那么当应用B被启动后,这个Activtiy的任务栈被从应用A中转移到应用B。

指定启动模式

一种方法:

<activity
            android:launchMode="singleInstance"
            android:taskAffinity="login"
            android:name=".activity.LoginActivity"
            android:label="@string/title_activity_login" />

另一种方法:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

这两种方法都可以指定启动模式,但是还是由区别的。首先,优先级上第二种更高,会覆盖第一种;其次,这两种方法在限定范围上不同,第一种无法直接为Activity设置FLAG_ACTIVITY_CLEAR_TOP标识,而第二种无法设置singleInstance。第二种方法可以更精细的指定,请看下面截图:
这里写图片描述
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值