您当前的位置:首页 > Android教程

Android开发学习教程(24)- Activity启动模式launchMode

时间:2022-01-20 07:18:47 阅读数:16,568人阅读
版权声明:转载请注明出处,谢谢!
—— 努力只能及格,拼命才能优秀。

简介

Activity 有四种不同的启动模式,这四种模式分别是:standard(默认),singleTop,singleTask,singleInstance。

预备知识

1. 任务栈(Task Stack)或者叫退回栈(Back Stack)介绍:

1.1 任务栈用来存放用户开启的Activity。

1.2 在应用程序创建之初,系统会默认分配给其一个任务栈(默认一个),并存储根Activity。

1.3 同一个Task Stack,只要不在栈顶,就是onStop状态:

1.4 新创建Activity会被压入栈顶。点击back会将栈顶Activity弹出,并产生新的栈顶元素作为显示界面(onResume状态)。

1.5 当Task最后一个Activity被销毁时,对应的应用程序被关闭,清除Task栈,但是还会保留应用程序进程(狂点Back退出到Home界面后点击Menu会发现还有这个App的框框。个人理解应该是这个意思),再次点击进入应用会创建新的Task栈。

2. Activity的affinity:

2.1 affinity是Activity内的一个属性(在ManiFest中对应属性为taskAffinity)。默认情况下,拥有相同affinity的Activity属于同一个Task中。

2.2 任务栈也有affinity属性,它的affinity属性由根Activity(创建Task时第一个被压入栈的Activity)决定。

2.3 在默认情况下(我们什么都不设置),所有的Activity的affinity都从Application继承。也就是说Application同样有taskAffinity属性。Application默认的affinity属性为Manifest的包名。

3. 如何在代码中获取 Activity 的 taskAffinity 属性值:

	    // 当前 Activity 的 taskAffinity 属性值 
		String taskAffinity = "";
		try {
			ActivityInfo activityInfo = getPackageManager().getActivityInfo(getComponentName(),
					PackageManager.GET_META_DATA);
			taskAffinity = activityInfo.taskAffinity;
		} catch (PackageManager.NameNotFoundException e) {
			e.printStackTrace();
		}
	

Activity启动模式

1. 默认启动模式standard:

该模式可以被设定,不在manifest设定时候,Activity的默认模式就是standard。在该模式下,启动的Activity会依照启动顺序被依次压入Task中:

上面这张图讲的已经很清楚了,我想应该不用做什么实验来论证了吧,这个是最简单的一个,我们过。

2. 栈顶复用模式singleTop:

在该模式下,如果栈顶Activity为我们要新建的Activity(目标Activity),那么就不会重复创建新的Activity。

这次我们来用代码举例:

		<?xml version="1.0" encoding="utf-8"?>
		<manifest xmlns:android="http://schemas.android.com/apk/res/android"
			package="zy.pers.activitytext">
		 
			<application
				android:allowBackup="true"
				android:icon="@mipmap/ic_launcher"
				android:label="@string/app_name"
				android:roundIcon="@mipmap/ic_launcher_round"
				android:supportsRtl="true"
				android:taskAffinity="gf.zy"
				android:theme="@style/AppTheme">
				<activity android:name=".MainActivity">
					<intent-filter>
						<action android:name="android.intent.action.MAIN" />
		 
						<category android:name="android.intent.category.LAUNCHER" />
					</intent-filter>
				</activity>
				<activity android:name=".TwoActivity"
					android:launchMode="singleTop">
					<intent-filter>
						<action android:name="ONETEXT_TWOACTIVITY" />
						<category android:name="android.intent.category.DEFAULT" />
					</intent-filter>
				</activity>
				<activity android:name=".ThreeActivity">
					<intent-filter>
						<action android:name="ONETEXT_THREEACTIVITY" />
						<category android:name="android.intent.category.DEFAULT" />
					</intent-filter>
				</activity>
			</application>
		 
		</manifest>
	

这是Mainfest结构,里面创建了三个Activity,我们把TwoActivity的模式设置为singleTop。

每个Activity界面都只有一个显示当前界面名称的TextView和一个用来组跳转的Button,所以应用OneText的功能就是从活动1跳转到活动2,活动2继续跳转活动2,代码在文章最后可以下载

我们发现在我们跳转到TwoActivity之后,继续点击跳转到TwoActivity时候,页面没有跳转动作。

3. 栈内复用模式singleTask:

与singleTop模式相似,只不过singleTop模式是只是针对栈顶的元素,而singleTask模式下,如果task栈内存在目标Activity实例,则:

1.将task内的对应Activity实例之上的所有Activity弹出栈。

2.将对应Activity置于栈顶,获得焦点。

同样我们也用代码来实现一下这个过程。还是刚才的那一坨代码,只是我们修改一下MainActivity的launchMode为singleTask,TwoActivity、ThreeActivity不设置launchMode属性,然后让TwoActivity跳转到ThreeActivity,让ThreeActivity跳转到MainActivity,代码在文章最后可以下载

我们发现在跳回MainActivity之后点击back键发现直接退回到首页了,这说明此时的MainActivity为task内的最后一个Activity。

4. 全局唯一模式singleInstance:

这是我们最后的一种启动模式,也是我们最恶心的一种模式:在该模式下,我们会为目标Activity分配一个新的affinity,并创建一个新的Task栈,将目标Activity放入新的Task,并让目标Activity获得焦点。新的Task有且只有这一个Activity实例。如果已经创建过目标Activity实例,则不会创建新的Task,而是将以前创建过的Activity唤醒(对应Task设为Foreground状态)

我们还是用代码来实现一下这个过程。还是刚才的那一坨代码,只是我们修改TwoActivity的launchMode为singleInstance,MainActivity、ThreeActivity不设置launchMode属性,然后让MainActivity跳到TwoActivity,TwoActivity跳到ThreeActivity,ThreeActivity再跳到TwoActivity然后依次点击返回键

我们发现在ThreeActivity跳到TwoActivity的时候此时任务栈里存在着两个不同的栈ID,然后依次在点击back键的时候,TwoActivity只出现了一次。

这里顺带一提,如果Activity启动模式为singleTop、singleTask、singleInstance并且任务栈里已经有该Activity的情况下,那么再次启动或回到这个Activity的时候,不会创建新的实例,也就是不会执行onCreate方法,而是执行onNewIntent方法。具体用法可以见singleInstance实例中的用法。

本篇源码下载地址:https://pan.baidu.com/s/16FJs9fz5zS0QlZB6aj9OSg 提取码: helu

------转载请注明出处,感谢您对原创作者的支持------

有偿提供技术支持、Bug修复、项目外包、毕业设计、大小作业

Android学习小站

Q Q:1095817610

微信:jx-helu

邮箱:1095817610@qq.com

添加请备注"Android学习小站"