Activity的四种launchMode。

launchMode在多个Activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的Activity实例,是否重用已存在的Activity实例,是否和其他Activity实例公用一个task里。这里简单介绍一下task的概念,task是一个具有栈结构的对象,一个task可以管理多个Activity,启动一个应用,也就创建一个与之对应的task。

Activity一共有以下四种launchMode:

1.standard

2.singleTop

3.singleTask

4.singleInstance

我们可以在AndroidManifest.xml配置<activity>的android:launchMode属性为以上四种之一即可。

下面我们结合实例一一介绍这四种lanchMode:

1.standard

standard模式是默认的启动模式,不用为<activity>配置android:launchMode属性即可,当然也可以指定值为standard。

我们将会一个Activity,命名为FirstActivity,来演示一下标准的启动模式。FirstActivity代码如下:

[java] view plain copy print ?
  1. package com.scott.launchmode;
  2. import android.app.Activity;
  3. import android.content.Intent;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.widget.Button;
  7. import android.widget.TextView;
  8. public class FirstActivity extends Activity {
  9. @Override
  10. public void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.first);
  13. TextView textView = (TextView) findViewById(R.id.textView);
  14. textView.setText(this.toString());
  15. Button button = (Button) findViewById(R.id.button);
  16. button.setOnClickListener(new View.OnClickListener() {
  17. @Override
  18. public void onClick(View v) {
  19. Intent intent = new Intent(FirstActivity.this, FirstActivity.class);
  20. startActivity(intent);
  21. }
  22. });
  23. }
  24. }
package com.scott.launchmode;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;public class FirstActivity extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.first);TextView textView = (TextView) findViewById(R.id.textView);textView.setText(this.toString());Button button = (Button) findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(FirstActivity.this, FirstActivity.class);startActivity(intent);}});}
}

我们FirstActivity界面中的TextView用于显示当前Activity实例的序列号,Button用于跳转到下一个FirstActivity界面。

然后我们连续点击几次按钮,将会出现下面的现象:

我们注意到都是FirstActivity的实例,但序列号不同,并且我们需要连续按后退键两次,才能回到第一个FristActivity。standard模式的原理如下图所示:

如图所示,每次跳转系统都会在task中生成一个新的FirstActivity实例,并且放于栈结构的顶部,当我们按下后退键时,才能看到原来的FirstActivity实例。

这就是standard启动模式,不管有没有已存在的实例,都生成新的实例。

2.singleTop

我们在上面的基础上为<activity>指定属性android:launchMode="singleTop",系统就会按照singleTop启动模式处理跳转行为。我们重复上面几个动作,将会出现下面的现象:

我们看到这个结果跟standard有所不同,三个序列号是相同的,也就是说使用的都是同一个FirstActivity实例;如果按一下后退键,程序立即退出,说明当前栈结构中只有一个Activity实例。singleTop模式的原理如下图所示:

正如上图所示,跳转时系统会先在栈结构中寻找是否有一个FirstActivity实例正位于栈顶,如果有则不再生成新的,而是直接使用。也许朋友们会有疑问,我只看到栈内只有一个Activity,如果是多个Activity怎么办,如果不是在栈顶会如何?我们接下来再通过一个示例来证实一下大家的疑问。

我们再新建一个Activity命名为SecondActivity,如下:

[java] view plain copy print ?
  1. package com.scott.launchmode;
  2. import android.app.Activity;
  3. import android.content.Intent;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.widget.Button;
  7. import android.widget.TextView;
  8. public class SecondActivity extends Activity {
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.second);
  13. TextView textView = (TextView) findViewById(R.id.textView);
  14. textView.setText(this.toString());
  15. Button button = (Button) findViewById(R.id.button);
  16. button.setOnClickListener(new View.OnClickListener() {
  17. @Override
  18. public void onClick(View v) {
  19. Intent intent = new Intent(SecondActivity.this, FirstActivity.class);
  20. startActivity(intent);
  21. }
  22. });
  23. }
  24. }
package com.scott.launchmode;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;public class SecondActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.second);TextView textView = (TextView) findViewById(R.id.textView);textView.setText(this.toString());Button button = (Button) findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(SecondActivity.this, FirstActivity.class);startActivity(intent);               }});}
}

然后将之前的FirstActivity跳转代码改为:

[java] view plain copy print ?
  1. Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
  2. startActivity(intent);
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);

是的,FirstActivity会跳转到SecondActivity,SecondActivity又会跳转到FirstActivity。演示结果如下:

我们看到,两个FirstActivity的序列号是不同的,证明从SecondActivity跳转到FirstActivity时生成了新的FirstActivity实例。原理图如下:

我们看到,当从SecondActivity跳转到FirstActivity时,系统发现存在有FirstActivity实例,但不是位于栈顶,于是重新生成一个实例。

这就是singleTop启动模式,如果发现有对应的Activity实例正位于栈顶,则重复利用,不再生成新的实例。

3.singleTask

在上面的基础上我们修改FirstActivity的属性android:launchMode="singleTask"。演示的结果如下:

我们注意到,在上面的过程中,FirstActivity的序列号是不变的,SecondActivity的序列号却不是唯一的,说明从SecondActivity跳转到FirstActivity时,没有生成新的实例,但是从FirstActivity跳转到SecondActivity时生成了新的实例。singleTask模式的原理图如下图所示:

在图中的下半部分是SecondActivity跳转到FirstActivity后的栈结构变化的结果,我们注意到,SecondActivity消失了,没错,在这个跳转过程中系统发现有存在的FirstActivity实例,于是不再生成新的实例,而是将FirstActivity之上的Activity实例统统出栈,将FirstActivity变为栈顶对象,显示到幕前。也许朋友们有疑问,如果将SecondActivity也设置为singleTask模式,那么SecondActivity实例是不是可以唯一呢?在我们这个示例中是不可能的,因为每次从SecondActivity跳转到FirstActivity时,SecondActivity实例都被迫出栈,下次等FirstActivity跳转到SecondActivity时,找不到存在的SecondActivity实例,于是必须生成新的实例。但是如果我们有ThirdActivity,让SecondActivity和ThirdActivity互相跳转,那么SecondActivity实例就可以保证唯一。

这就是singleTask模式,如果发现有对应的Activity实例,则使此Activity实例之上的其他Activity实例统统出栈,使此Activity实例成为栈顶对象,显示到幕前。

4.singleInstance

这种启动模式比较特殊,因为它会启用一个新的栈结构,将Acitvity放置于这个新的栈结构中,并保证不再有其他Activity实例进入。

我们修改FirstActivity的launchMode="standard",SecondActivity的launchMode="singleInstance",由于涉及到了多个栈结构,我们需要在每个Activity中显示当前栈结构的id,所以我们为每个Activity添加如下代码:

[java] view plain copy print ?
  1. TextView taskIdView = (TextView) findViewById(R.id.taskIdView);
  2. taskIdView.setText("current task id: " + this.getTaskId());
TextView taskIdView = (TextView) findViewById(R.id.taskIdView);
taskIdView.setText("current task id: " + this.getTaskId());

然后我们再演示一下这个流程:

我们发现这两个Activity实例分别被放置在不同的栈结构中,关于singleInstance的原理图如下:

我们看到从FirstActivity跳转到SecondActivity时,重新启用了一个新的栈结构,来放置SecondActivity实例,然后按下后退键,再次回到原始栈结构;图中下半部分显示的在SecondActivity中再次跳转到FirstActivity,这个时候系统会在原始栈结构中生成一个FirstActivity实例,然后回退两次,注意,并没有退出,而是回到了SecondActivity,为什么呢?是因为从SecondActivity跳转到FirstActivity的时候,我们的起点变成了SecondActivity实例所在的栈结构,这样一来,我们需要“回归”到这个栈结构。

如果我们修改FirstActivity的launchMode值为singleTop、singleTask、singleInstance中的任意一个,流程将会如图所示:

singleInstance启动模式可能是最复杂的一种模式,为了帮助大家理解,我举一个例子,假如我们有一个share应用,其中的ShareActivity是入口Activity,也是可供其他应用调用的Activity,我们把这个Activity的启动模式设置为singleInstance,然后在其他应用中调用。我们编辑ShareActivity的配置:

[html] view plain copy print ?
  1. <activity android:name=".ShareActivity" android:launchMode="singleInstance">
  2. <intent-filter>
  3. <action android:name="android.intent.action.MAIN" />
  4. <category android:name="android.intent.category.LAUNCHER" />
  5. </intent-filter>
  6. <intent-filter>
  7. <action android:name="android.intent.action.SINGLE_INSTANCE_SHARE" />
  8. <category android:name="android.intent.category.DEFAULT" />
  9. </intent-filter>
  10. </activity>
        <activity android:name=".ShareActivity" android:launchMode="singleInstance"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter><intent-filter><action android:name="android.intent.action.SINGLE_INSTANCE_SHARE" /><category android:name="android.intent.category.DEFAULT" /></intent-filter></activity>

然后我们在其他应用中这样启动该Activity:

[java] view plain copy print ?
  1. Intent intent = new Intent("android.intent.action.SINGLE_INSTANCE_SHARE");
  2. startActivity(intent);
Intent intent = new Intent("android.intent.action.SINGLE_INSTANCE_SHARE");
startActivity(intent);

当我们打开ShareActivity后再按后退键回到原来界面时,ShareActivity做为一个独立的个体存在,如果这时我们打开share应用,无需创建新的ShareActivity实例即可看到结果,因为系统会自动查找,存在则直接利用。大家可以在ShareActivity中打印一下taskId,看看效果。关于这个过程,原理图如下:

基础总结篇:Activity的四种launchMode相关推荐

  1. 基础总结篇之二:Activity的四种launchMode

    合抱之木,生於毫末:九層之台,起於累土:千里之行,始於足下.<老子> 今天在社区看到有朋友问"如何在半年内成为顶级架构师",有网友道"关灯睡觉,不用半年的.. ...

  2. (转)Activity的四种launchMode

    以下内容来自: 基础总结篇之二:Activity的四种launchMode http://blog.csdn.net/liuhe688/article/details/6754323 launchMo ...

  3. Activity生命周期Android,横屏切换不重新创建Activity, Activity的四种launchMode

    Activity生命周期 1.启动Activity:系统会先调用onCreate方法,然后调用onStart方法,最后调用onResume,Activity进入运行状态. 2.当前Activity被其 ...

  4. Activity的四种launchMode

    我们今天要讲的是Activity的四种launchMode. launchMode在多个Activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的Activity实例,是否重用已存在的Act ...

  5. 【Android】Activity的四种launchMode

    转自:http://blog.csdn.net/liuhe688/article/details/6754323 合抱之木,生於毫末:九層之台,起於累土:千里之行,始於足下.<老子> 今天 ...

  6. 安卓四种launchMode的理解

    反正 就是想起啥就看点啥,记点啥 今天看到,  隐约记得以前应该也是有去看过然后了解过的,但是当我再一次看到这个的时候还是,emmm,不知道具体啥意思.小计一下,增加印象. 1.安卓中有四种launc ...

  7. 【Android笔记】Activity的四种启动模式

    在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity. 可能会希望一个Activity跳转到原来某个Activity实例,而不是产生大量重复 ...

  8. 区分Activity的四种加载模式

    在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity.可能会希望跳转到原来某个Activity实例,而不是产生大量重复的Activity. ...

  9. 区分Activity的四种加载模式(转)

    转自:http://marshal.easymorse.com/archives/2950 在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activi ...

  10. Android Activity:四种启动模式,Intent Flags和任务栈(转自他人博客)

    在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.那各个页面跳转关系如何决定呢?如果启动了顺序启动了ABCD的Activiy,如何从D调回 ...

最新文章

  1. java基础入门传智播客 源码_Java-_2020年版Java零基础视频教程(Java 0基础,Java初学入门)魔鬼讲师老杜出品...
  2. canvas中的碰撞检测笔记
  3. 【Linux系统编程】文件IO操作
  4. 重磅!阿里巴巴和全球最大奢侈品电商YNAP成立合资公司
  5. django mysql5.7_GitHub - qiubiteme/DjangoBloger: 一个Django2.0+mysql57,实现的响应式博客
  6. 计算机设备记录人耳感知不到的声音,现代教育技术考试复习资料新
  7. java-String类
  8. 如何从0-1制作数据大屏,我用大白话给你解释清楚了
  9. (转)Android属性设置android:noHistory=true
  10. 【翻译】五步快速使用LINQPad尝鲜StreamInsight
  11. 自己动手写CPU之第五阶段(1)——流水线数据相关问题
  12. 大数据实效_新都区:运用“大数据”提升专项巡察实效
  13. bilibili ,B站视频预览缩略图实现分析
  14. vue各模块功能范围,webpack属性配置
  15. 手机抓包软件:charles安装及教程
  16. word设置图标索引
  17. 《程序员延寿指南》火爆 GitHub,日涨 1500+ 星,优秀 !
  18. 情报学的主要学术期刊
  19. js绘制的漂亮玫瑰曲线rose curve
  20. PLM系统的技术现状和发展趋势

热门文章

  1. Vue.js 2.0 学习笔记(五)路由
  2. 一文带你入门虚拟遗憾最小化CFR算法
  3. 用Python制作塔防小游戏
  4. 超全面教程!给照片添加文字有哪10个高大上的方法?
  5. 计算机组成原理期末复习总结
  6. 用纯CSS创建一个三角形
  7. 人工神经网络与Stata应用
  8. 男人去除黑眼圈的方法 去黑眼圈食谱
  9. 计算机向使用者传递计算处理结果的设备称为输出设备
  10. 从Compaq Visual Fortran到Intel Visual Fortran