在AndroidManifest.xml中配置activity时,android:launchMode属性会指定启动activity的模式,有四种:

standard

singleTop

singleTask

singleInstance

这四种模式一般配合Intent属性变量FLAG_ACTIVITY_XXX使用,比如FLAG_ACTIVITY_NEW_TASK,本文暂时撇开FLAG_ACTIVITY_XXX,只讨论这四种模式的启动结果,先考虑只在同一个应用下的情况。

standard模式

系统默认情况下就是standard模式,假如A中设置为默认模式,A中有一个按钮,单击按钮时只启动自己,看看启动后的结果。AndroidManifest.xml、A和源码及布局分别为:

AndroidManifest.xml
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.administrator.myapplication">
 
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name="com.example.administrator.myapplication.AActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.feeyan.www.a_activity"></action>
                <category android:name="android.intent.category.DEFAULT"></category>
            </intent-filter>
        </activity>
    </application>
 
</manifest>
AActivity.java
 
1
2
3
4
5
6
7
8
9
10
11
12
public class AActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.a_layout);
    }
 
    public void startToB(View view) {
        startActivity(new Intent("com.feeyan.www.a_activity"));
    }
}
a_layout.xml
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.administrator.myapplication.AActivity">
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
 
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="to B"
        android:id="@+id/button"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:textSize="20sp"
        android:onClick="startToB" />
</RelativeLayout>

注:本文案例在小米4上测试

假设现在没有运行程序,先通过命令dumpsys activity activities在串口中查看所有activity栈信息:

看红色区域,activity栈中只有一个代号为0的栈,栈中也只有一个id号为#1的task和id号为#0的ActivityRecord,ActivityRecord中保存的包名是com.miui.home,启动类名为.launcher.Launcher,也就是说,目前Activity栈中只有Launcher应用,没有别的应用。

现在启动案例,启动后的栈信息:

案例启动后,系统新建了一个栈stack #1,其中有新启动的Activity实例AActivity,保存在id号为#24的task中

然后,点击按钮再次启动AActivity,启动后的栈信息为:

在同样的stack #1、同样的task #24中多了一个AActicity实例,两个实例对应的ActivityRecord地址不一样,一个是42e23ae0,一个是42da3a08。

默认标准模式,每启动一次,就创建一个新实例,并放到栈顶,并且该实例放在同样的任务task中、同样的activity栈中。不会再新创建栈、task。

singleTop模式

如果把A设为默认Standard标准模式,把B设置singleTop模式,A启动B后看看什么情况,相关源码较简单,不再添加,本文后又源码下载地址。

在stack #1中,新创建了一个task #25,包含B实例和A实例,新启动的实例位于栈顶。如果在B中点击按钮再次启动B,发现栈信息不会改变,而且无论点击多少次按钮,stack #1栈中还是B和A,不会重新创建实例。

假设在A中启动B,B启动C,C设为标准模式,启动后的栈信息:

栈顶是C,其次是B和A,A在栈最底部;如果此时在C中点击按钮再启动B呢?启动后的栈信息:

发现栈顶又创建了一个B实例,不会复用栈中已有的实例,栈中总共有2个B实例!

singleTop模式跟标准Standard模式差不多,只不过多了一种情况,分为两种情况来看:

1.  如果栈中已经有了待启动activity实例并且位于栈顶,那么再次启动该activity时,系统会直接复用该实例,不会再创建新的实例;如果没有,就新创建实例,并放到栈顶;

2. 如果栈中已经有了待启动activity实例,但不在栈顶,那么再次启动该activity时,系统会再次创建新的实例并将该实例放到栈顶,这种情况和standard模式一样。

singleTask模式

如果A和C设置standard模式,B设为singleTask模式,A启动B,B启动C,按照这个顺序启动后,栈中自底向上为:A—–B—–C,如果此时在C中点击按钮再次启动B呢?启动后栈信息为:

此时,Task #30中只有A和B,B位于栈顶,没有C了,这个和singleTop有了明显的差别,在singleTop中C不会消失,而此时C却消失了。

1.  如果栈中已经有了待启动activity实例并且位于栈顶,那么再次启动该activity时,系统会直接复用该实例,不会再创建新的实例;如果没有,就新创建实例,并放到栈顶;

2. 如果栈中已经有了待启动activity实例但不在栈顶,那么再次启动该activity时,系统会复用已有实例,并且把位于该实例之上的所有其他activity实例移出栈,同时将该实例放在栈顶。

singleInstance模式

如果设A和C为standard模式,B为singleInstance模式,A启动B后栈信息为:

发现和上面三种情况都不一样的地方,在栈中新创建了一个task,并把B放入其中,上面三种情况都是在同样的task中。如果再B中启动C,启动后的栈:

A和C都是标准模式,都在同一个task中,而B在另外一个task中,因为启动了C,C在栈顶。如果再C中点击按钮再次启动B,结果会是什么?

B所在的task跑到了栈顶,A和C所在的task在栈底。而且B始终只有一个实例。

1.  如果栈中没有待启动activity实例,启动该activity时,系统会新创建一个task,再创建一个待启动activity实例,把该实例放到新task中,并且该task会在栈顶;

2. 如果栈中已经有了待启动activity实例,不管在栈的什么位置,系统都会复用已存在实例,并且把该实例放在栈顶,而且该task中只有一个该实例,不会再有第二个实例,也不会有其他activity实例;

3. 如果一个应用中有多个activity都设置成singleInstance模式,那么每个启动后的activity实例都保存在一个task中,不会在同一个task中,task和实例是一对一关系。

同一应用中测试小结

a. standard、singleTop存在多种实例的可能(“可能”二字表明,singleTop情况下,如果栈顶已有实例,再次启动时只会复用,如果不在栈顶,就会新创建实例);而singleTask和singleInstance只有一个实例,再次启动时不会创建新实例;

b. singleTask和singleInstance模式,再次调用时都会先调用onNewIntent方法,再调用onResume方法;对于singleTop,如果栈顶已有实例,也是先调用onNewIntent方法,再调用onResume方法,如果不在栈顶或者还没有实例,就会先调用onCreate方法;

c. singleInstance模式不同于其他三种,首次启动时会新开启一个task,该task只包含一个实例;再次启动时只会复用该task,不再新创建。

同一应用中只有1个app,源码地址:https://yunpan.cn/crybfHCWhcbwW  访问密码:e7cb

不同应用之间测试小结

上面分析了在同一应用中的情况,再看看不同应用之间的情形。通过测试得知:standard、singleTop没有什么改变,还是在在同样的栈、task中;singleInstance模式下也没有改变,还是会创建新的task并保存唯一实例;但singleTask却不一样,首次启动时,系统会在当前栈中创建一个新的task,再次启动时,复用已有task;而在同一应用中,再次启动时,不会再创建新task的,直接复用已有task。

不同应用之间测试有2个app,源码地址:https://yunpan.cn/crKLt2CuZ7drc  访问密码 e4b8

最终总结

不管是同一应用中还是不同应用之间,standard、singleTop、singleInstance各自没有区别,只有singleTask不一样,同一应用中不创建新的task,不同应用中有可能会创建新的task。(注:这里用到了“可能”二字,没有用“一定”,是因为这与taskAffinity属性有关,如果设置了此属性,就会在该属性对应的task中启动实例,否则,会创建新的task)。

转自:feeyan

Android启动activity的4种模式(standard、singleTop、singleTask、singleINstance)的更多相关文章

  1. Android -- Activity的生命周期,Activity四种启动模式 Standard, SingleTop,SingleTask,SingleInstance

    1. 示例图 . 这七个方法定义了Activity的完整生命周期.实现这些方法可以帮助我们监视其中的三个嵌套生命周期循环:  Activity的完整生命周期自第一次调用onCreate()开始,直至调 ...

  2. Android启动Activity的两种方式与四种启动模式

    1.在一个Activity中调用startActivity()方法 2.在一个Activity中调用startActivityRequest()方法. 重写onActivityResult方法,用来接 ...

  3. Android学习笔记_50_(转 四种加载方式详解(standard singleTop singleTask singleInstance)

    Android之四种加载方式 (http://marshal.easymorse.com/archives/2950 图片) 在多Activity开发中,有可能是自己应用之间的Activity跳转,或 ...

  4. Android 四种加载方式详解(standard singleTop singleTask singleInstance) .

    Android之四种加载方式 (http://marshal.easymorse.com/archives/2950 图片) 在多Activity开发中,有可能是自己应用之间的Activity跳转,或 ...

  5. Activity的启动模式全解standard,singleTop,singleTask,singleInstance

    在android中控制Activity的启动模式的属性主要控制两大功能: 1,控制activity 进入哪一个任务task 中,   有两种可能,进入启动task中,进入指定taskAffinity的 ...

  6. "standard,singleTop,singleTask,singleInstance"-Android启动模式

    安卓有4种启动模式,下面我们就进行详细的讲解 用栈的思维去理解,就能理解这些启动模式的本质了 先设置两个页面: A(为测试对象),B两个页面,两个页面都有跳至对方的按钮 一.标准模式(standard ...

  7. Android [启动方式:standard singleTop singleTask singleInstance]

    栈顶Activity是当前正在显示的. 以A.B举例 1.standard 不同的Activity都存放在同一个栈中,每次创建实例都会堆放到栈顶,逐次返回直至退出. 创建实例B 创建实例A 点击返回时 ...

  8. Android 启动Activity的方式

    Activity的启动分为两种方式,显示方式和隐式方式,显示方式就是在通过intent启动Activity时指定了Activity的包名和类名. 而隐式方式则在初始化Intent时仅仅指定action ...

  9. Android系统中的6种模式

    Android系统中的6种模式 1:一般启动模式(normal mode):    功能是正常启动手机,方法为关机状态下按电源键启动. 2:安全模式(safe mode):    此模式和正常启动一样 ...

随机推荐

  1. 被遗忘的Android mipmaps简介

    被遗忘的 Android mipmaps 简介 [导读]已经发布的 Android Studio1.1 版本是一个 bug 修复版本.在这个版本中,当你创建工程时一项改变将会吸引你的眼球.工程创建登陆 ...

  2. POJ3461 Oulipo KMP算法

    这个算法去年的这个时候就已经听过了,看毛片算法哈哈..不过理解它确实花了我很久的时间..以致于我一直很排斥字符串的学习,因为总觉得太难了,但是有些硬骨头还是要啃的,这个寒假就啃啃字符串还有一些别的东西 ...

  3. POJ 1666

    #include<iostream> using namespace std; int main() { int num_stu; int i; ; do{ time=; cin>& ...

  4. hdu 4676 Sum Of Gcd

    离线+分块!! 思路:序列a[1],a[2],a[3]……a[n] num[i]表示区间[L,R]中是i的倍数的个数:euler[i]表示i的欧拉函数值. 则区间的GCD之和sum=∑(C(num[i ...

  5. Android 程序运行之后,禁止休眠

    在程序中添加 // 禁止休眠功能 getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager. ...

  6. 李洪强iOS开发之【零基础学习iOS开发】【01-前言】01-开篇

    从今天开始,我就开始更新[零基础学习iOS开发]这个专题.不管你是否涉足过IT领域,也不管你是理科生还是文科生,只要你对iOS开发感兴趣,都可以来阅读此专题.我尽量以通俗易懂的语言,让每个人都能够看懂 ...

  7. 包装类型的比较,如:Integer,Long,Double

    Integer, Long, Double等基本类型的包装类型,比较时两种方法:第一种:equals,  第二种: .intValue(),  .longValue() ,  .doubleValue ...

  8. java:线程的简单控制方法

    中断线程方法 休眠:sleep(); 主动让出cpu:yield(); 设置线程优先级: 取值:getPriority(); 设置:setPriority(..); MAX_PRIORITY最大优先级 ...

  9. C++:this指针

    this指针 this关键字:表示本类中的对象成员,可以通过this指针访问当前类的成员//举例 //例 3.18 隐藏this指针的引例 #include<iostream> using ...

  10. 深度神经网络如何看待你,论自拍What a Deep Neural Network thinks about your #selfie

    Convolutional Neural Networks are great: they recognize things, places and people in your personal p ...