# 复习安卓开发经典知识
背景:
安卓系统给每个正在运行的App都分配了活动栈,栈里面容纳着已经创建且尚未销毁的活动信息。鉴于栈是一种先进后出、后进先出的数据结构,故而后面入栈的活动总是先出栈。
但我们可以在开发时根据需要配置(默认为Standard,先进先出),打破这种先进先出的规则,以达到我们的业务需求。
常用的启动标志:
有两种方式:
1. 在配置文件 AndroidManifest.xml 中指定启动模式:
示例:
<activity
android:name=".LoginInputActivity"
android:exported="true"
android:launchMode="standard">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
通过 launchMode 属性配置,其中 standard 是默认属性,还有这些属性:
它们分别代表的意义如下:
launchMode 属性值 | 说明 |
---|---|
standard | 标准模式,无论何时启动哪个活动,都是重新创建该页面的实例并放入栈顶。如果不指定 launchMode 属性,则默认为标准模式 |
singleTop | 启动新活动时,判断如果栈顶正好就是该活动的实例,则重用该实例;否则创建新的实例并放入栈顶,也就是按照 standard 模式处理 |
singleTask | 启动新活动时,判断如果栈中存在该活动的实例,则重用该实例,并清除位于该实例上面的所有实例;否则按照 standard 模式处理 |
singleInstance | 启动新活动时,将该活动的实例放入一个新栈中,原栈的实例列表保持不变 |
2. 在代码中设置启动标志
他们的意义如下:
- Intent.FLAG_ACTIVITY_NEW_TASK:开辟一个新的任务栈
- Intent.FLAG_ACTIVITY_SINGLE_TOP:当栈顶为待跳转的活动实例之时,则重用栈顶的实例
- Intent.FLAG_ACTIVITY_CLEAR_TOP:当栈中存在待跳转的活动实例时,则重新创建一个新实例,并清除原实例上方的所有实例
- Intent.FLAG_ACTIVITY_CLEAR_TASK:跳转到新页面时,栈中的原有实例都被清空
通常情况下配置文件设置启动模式和代码设置启动模式配合使用。
例子1:在两个活动之间交替跳转
假设活动A有个按钮,点击该按钮会跳到活动B;同时活动B也有个按钮,点击按钮会跳到活动A;从首页 打开活动A之后,就点击按钮在活动A与活动B之间轮流跳转。如果反复在A页面和B页面点击,那么用户在返回的时候就可能反复的在A页面和B页面横跳,影响用户体验。(用户期望从B页面范围到A页面后直接退出APP)
对于不允许重复返回的情况,可以设置启动标志:FLAG_ACTIVITY_CLEAR_TOP
它表示当发生Activity的跳转时,清除跳转 Activity 所在任务栈中位于它之上的所有 Activity,并将目标 Activity 置于栈顶(如果已存在)。如果目标 Activity 不存在,则创建新实例。
举例:
假设任务栈结构为:A → B → C → D
(A 是栈底,D 是栈顶)。
当从 D 启动 B 并设置 FLAG_ACTIVITY_CLEAR_TOP
时:
- 系统会清除 B 之上的所有 Activity(即 C、D 被销毁)。
- 最终任务栈变为:
A → B
(B 成为栈顶,复用已存在的实例)。
示例代码:
@Override
public void onClick(View v) {
Intent intent = new Intent(this, JumpSecondActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
例子2:登录成功后不再返回登录页面
很多App第一次打开都要求用户登录,登录成功再进入App首页,如果这时按下返回键,发现并没有回 到上一个登录页面,而是直接退出App。因为用户登陆过一次后就不用再登录了,此时返回登录的Activity界面没意义了。因此如果用户按下返回,就会直接退出APP。?不光登录页面,登录之前的其他页面包括获取验证码、找回密码等页面都不应该回去。
对于这种情况,我们可以设置启动标志:
FLAG_ACTIVITY_CLEAR_TASK 和 FLAG_ACTIVITY_NEW_TASK 配合使用
其中:
Intent.FLAG_ACTIVITY_CLEAR_TASK 表示跳转到新页面时,原栈中的原有实例都被清空
Intent.FLAG_ACTIVITY_NEW_TASK 表示开辟一个新的任务栈
示例代码:
@Override
public void onClick(View v) {
Intent intent=new Intent(this, LoginSuccessActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK |Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}