Android开发学习教程(24)- Activity启动模式launchMode
—— 努力只能及格,拼命才能优秀。
简介
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学习小站"
