Activity的四种launchMode

2017-10-13 16:21:29

合抱之木,生於毫末;九層之台,起於累土;千里之行,始於足下。《老子》

今天在社区看到有朋友问“如何在半年内成为顶级架构师”,有网友道“关灯睡觉,不用半年的...”,的确,做梦还来的快一些。作为一个程序员,树立远大的目标是值得欣赏的,但不能只去空想,要一步一步地实践才行。成大事者,须从小事做起;万事起于忽微,量变引起质变。

我们今天要讲的是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

  1. package com.scott.launchmode;  

  2.   

  3. import android.app.Activity;  

  4. import android.content.Intent;  

  5. import android.os.Bundle;  

  6. import android.view.View;  

  7. import android.widget.Button;  

  8. import android.widget.TextView;  

  9.   

  10. public class FirstActivity extends Activity {  

  11.     @Override  

  12.     public void onCreate(Bundle savedInstanceState) {  

  13.         super.onCreate(savedInstanceState);  

  14.         setContentView(R.layout.first);  

  15.         TextView textView = (TextView) findViewById(R.id.textView);  

  16.         textView.setText(this.toString());  

  17.         Button button = (Button) findViewById(R.id.button);  

  18.         button.setOnClickListener(new View.OnClickListener() {  

  19.             @Override  

  20.             public void onClick(View v) {  

  21.                 Intent intent = new Intent(FirstActivity.this, FirstActivity.class);  

  22.                 startActivity(intent);  

  23.             }  

  24.         });  

  25.     }  

  26. }  

我们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

  1. package com.scott.launchmode;  

  2.   

  3. import android.app.Activity;  

  4. import android.content.Intent;  

  5. import android.os.Bundle;  

  6. import android.view.View;  

  7. import android.widget.Button;  

  8. import android.widget.TextView;  

  9.   

  10. public class SecondActivity extends Activity {  

  11.     @Override  

  12.     protected void onCreate(Bundle savedInstanceState) {  

  13.         super.onCreate(savedInstanceState);  

  14.         setContentView(R.layout.second);  

  15.         TextView textView = (TextView) findViewById(R.id.textView);  

  16.         textView.setText(this.toString());  

  17.         Button button = (Button) findViewById(R.id.button);  

  18.         button.setOnClickListener(new View.OnClickListener() {  

  19.             @Override  

  20.             public void onClick(View v) {  

  21.                 Intent intent = new Intent(SecondActivity.this, FirstActivity.class);  

  22.                 startActivity(intent);                

  23.             }  

  24.         });  

  25.     }  

  26. }  

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



[java] view plain copy

  1. Intent intent = new Intent(FirstActivity.this, SecondActivity.class);  

  2. startActivity(intent);  

    • 2018-12-04 23:40:26

      pod删除已导入的第三方库和移除项目中的cocoapods

      CocoaPods是一个负责管理iOS项目中第三方开源库的工具。CocoaPods的项目源码在Github上管理。在我们有了CocoaPods这个工具之后,只需要将用到的第三方开源库放到一个名为Podfile的文件中,然后在命令行执行$ pod install命令。CocoaPods就会自动将这些第三方开源库的源码下载下来,并且为我的工程设置好相应的系统依赖和编译参数. 但是如果我们导入的某个第三方不适用,或者我们又不想使用该第三方,那我们又该如何将这些相关的东西从我们的项目中清理出去呢?

    • 2018-12-04 23:41:47

      制作自己的Pod库(公有/私有)

      目的:1.管理自己常用的类;2.组件化开发步骤:1.想一个比较酷的名字,在桌面简历文件夹。2.打开terminal,cd到这个文件夹下面,执行pod lib create  xxx(这里我们以JJCategoryKit为例子,下同)命令,如下图。这个过程会问几个问题,根据实际情况输入回答即可。这里我们选择添加demo,结束的时候会自动Lanuch这个app. 作者:深水日月 链接:https://www.jianshu.com/p/ece0b5721461 來源:简书 简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

    • 2018-12-05 06:08:26

      CocoaPods建立私有仓库 spec repo

      好多项目里都有公共的组件,copy来,copy去很容易出错,而且不容易维护,所以就想到用用cocoapods 建自己的私有库,Carthage用法虽然相对简单,但是它是把公共组件都放在framework里不容易单步调试,所以我还是选择用Cocoapods 来建立私有仓库 参考使用Cocoapods创建私有podspec

    • 2018-12-05 15:11:18

      为什么 Objective-C非常难

      作为一个Objective-C的coder,我总能听到一部 分人在这门语言上抱怨有很多问题。他们总在想快速学习这门语言来写一个App出来,但他们也总是联想到Objective-C看上去实在太难了或者在想这 些语法符号都是神马玩意?不错,他们问得非常好,所以本人也解释一下为什么很多程序员相比较学习Ruby或者Java很容易,但在决定开发iOS或者OS X应用时会那么犹豫。

    • 2018-12-05 15:22:23

      十分钟让你明白Objective-C的语法(和Java、C++的对比)

      很多想开发iOS,或者正在开发iOS的程序员以前都做过Java或者C++,当第一次看到Objective-C的代码时都会头疼,Objective-C的代码在语法上和Java, C++有着很大的区别,有的同学会感觉像是看天书一样。不过,语言都是相通的,有很多共性。下面列出Objective-C语言的语法和Java,C++的对比,这样你就会很容易Objective-C的语法是怎么回事了。

    • 2018-12-05 15:33:33

      一篇文章看懂有关iOS开发语言的一切!

      OS开发语言有哪些?OS开发语言主要包括什么?iOS开发语言具体怎么学习?今天重点介绍一下: iOS开发语言主要包括:C语言基础、Obiective-C编程、Swift、UIKit框架详解这几大块,在这里项目阶段就不详细的介绍了。 C语言基础 C语言是开发语言的基础,是最常用的一门程序设计语言,最常用于编写计算机程序。

    • 2018-12-06 10:03:36

      定时杀掉processlist sleep状态的线程

      由于程序设计的Bug,导致目前这个项目使用的数据库中有很多Sleep状态的线程。找了很多解决办法,还没发现最终有效的解决方案。只能临时使用如下方法: 编写shell文件,如killSleepProcess.sh

    • 2018-12-07 08:26:37

      mysql线程池和连接池的区别

      可能有的DBA会把线程池和连接池混淆,其实两者是有很大区别的,连接池一般在客户端设置,而线程池是在DB服务器上配置;另外连接池可以取到避免了连接频繁创建和销毁,但是无法取到控制MySQL活动线程数的目标,在高并发场景下,无法取到保护DB的作用。比较好的方式是将连接池和线程池结合起来使用。 作者:飞鸿无痕 链接:https://www.jianshu.com/p/88e606eca2a5 來源:简书 简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

    • 2018-12-07 17:47:24

      linux中wc命令用法

      Linux系统中的wc(Word Count)命令的功能为统计指定文件中的字节数、字数、行数,并将统计结果显示输出。