文章目录

  • Activity的四种启动模式
    • 一、Android 任务栈
      • 1.1 Android任务栈的概念
    • 二、四种启动模式
      • 2.1 standard
      • 2.2 singleTop
      • 2.3 singleTask
      • 2.4 singleInstance
    • 三、启动模式的使用
      • 3.1 在AndroidManifest.xml文件中配置
      • 3.2 通过Intent添加标志来识别

Activity的四种启动模式

Android开发者在AndroidManifest文件中一共设计了四种启动模式

  • standard
  • singleTop
  • singleTask
  • singleInstance

一、Android 任务栈

1.1 Android任务栈的概念

栈:先进后出的线性表
一个android应用程序功能通常会被拆分为多个Activity,而各个Activity之间通过Intent进行连接,android系统通过栈结构来保存整个程序的Activity,栈底的元素是整个栈任务的发起者。
正常情况下,当一个Activity启动了另一个Activity的时候,新启动的Activity就会置于任务栈的顶端,而启动它的Activity虽然功成身退,但依然保留在任务栈中,处于停止状态(如果没有finish),当用户按下返回键或者调用finish()方法时,系统会移除顶部的Activity,让后面的Activity恢复活动状态。但是,可以给Activity设置一些“特权”,来打破这种“和谐”的模式。这种特权,就是通过在AndroidManifest.xml文件中的属性android:launchMode来设置或者通过Intent的flag来设置的。

                                                                      
Intent intent = new Intent(this,MainActivity.class);        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);     // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        startActivity(intent);

二、四种启动模式

  • standard
  • singleTop
  • singleTask
  • singleInstance

2.1 standard


默认启动模式,当不指定Activity的启动模式,则使用这种启动方式启动Activity;这种启动方式每次都会创建新的实例,新创建的activity会置于栈顶。

   @Override    protected void onCreate(Bundle savedInstanceState) {        Log.e(TAG, "onCreate");        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        button = (Button) findViewById(R.id.button);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                testLauncherMode();            }        });    }    void testLauncherMode() {        Intent intent = new Intent(this, MainActivity.class);        startActivity(intent);    }


模型如下

2.2 singleTop


singleTop(栈顶复用模式),如果指定启动模式为singleTop模式,那么在启动时,系统会判断当前栈顶的Activity是不是要启动的Activity,如果是则不创建新的Activity而直接复用这个Activity,同时回掉Activity的onNewIntent方法;如果不是,则创建新的Activity,即使栈内已存在该Activity。

    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Log.e(TAG, "onCreate");        setContentView(R.layout.view_second);        Button button = (Button) findViewById(R.id.button2);        Button btnMySelf = findViewById(R.id.button3);        btnMySelf.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                startMySelf();            }        });        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                testSingleTopLauncherMode();            }        });    }    @Override    protected void onNewIntent(Intent intent) {        super.onNewIntent(intent);        Log.e(TAG,"onNewIntent");    }


模型如下

2.3 singleTask

栈内复用模式:但一个具有singleTask启动模式的Activity请求启动后,比如Activity A,系统首先会寻找是否存在A想要的任务栈,如果不存在,就重新创建一个任务栈,并将A的实例放入栈中。如果存在A所需要的任务栈,这时候要看A是否在栈中有实例存在,如果栈中不存在该实例,创建该Activity的实例并放入占中,如果栈中存在该Activity,复用该Activity,同时将位于该Activity上面的Activity全部销毁。

  • 比如:目前任务栈S1中情况为ABC,这时候ActivityD以singleTask模式请求启动,其所需要的任务栈为S2,由于S2和D的实例均不存在,所以系统会先创建S2,然后在创建D的实例并将其放入到S2中。
  • 如果D所需要的任务栈为S1,并且当前任务栈的情况为ADBC,根据栈内复用的原则,此时D不会重新创建,系统会把D切换到栈顶并调用其onNewIntent方法,同时由于singleTask具有clearTop的效果,会导致栈内所有在D上面的Activity全部出栈,于是S1中最终情况为AD。

参考自
作者:JxYoung
链接:https://www.jianshu.com/p/4c8d6e2117ac
來源:简书

这种启动模式的Activity在Android系统中只允许存在一个实例

如果系统中已经存在了该种启动模式的目标Activity,则系统并不会重新创建一个目标Activity,而是首先将持有目标Activity的整个任务栈都会被置于前台(用户可见),并且通过onNewIntent(
)方法将启动目标Activity的Intent传递给目标Activity,置于目标Activity拿到这个Intent之后要做什么操作,系统就不管了,随便你拿来干什么。

但是这里有个问题,就是目标Activity和源Activity是不是来自同一应用。

源Activity和目标Activity来自同一个应用

这种情况还要分两种情况说:

当前系统中还没有目标Activity的实例
这种情况最简单,直接在当前的任务栈中创建SingleTask模式的Activity并置于栈顶即可。

当前系统中已经存在目标Activity的实例
这种情况比较特殊,因为系统会把任务栈中目标Activity之上的所有Activity销毁,以让目标Activity处在栈顶的位置。

这里还要还要再提醒大家的是,因为目标Activity已经存在,系统不会重新创建,而是通过onNewIntent()的方式把Intent传递过来,这点和singleTop模式有些类似

源Activity和目标Activity来自不同应用 这种情况也要分两种情况说:

当前系统中还没有目标Activity的实例
这时系统首先会看任务管理器中是否有目标Actvity所在应用的任务栈?如果有的话,那就直接在目标Activity所在应用的任务栈的栈顶创建即可。

如果任务管理器中没有目标Activity所在应用的任务栈,系统就会创建其所在应用的任务栈和目标Activity,并且把目标Activity作为新建任务栈的根Activity。如下图所示

当前系统中已经存在目标Activity的实例
目标Activity所在任务栈会被置于前台(即用户可见),而且也会把目标Activity之上的所有Actvity全部销毁。

2.4 singleInstance

这种启动模式和singleTask几乎一样,它也只允许系统中存在一个目标Activity,包括上面我们所说的SingleTask的一些特性singleInstance都有。singleInstance翻译过来是单例的意思:TA有两层含义:1.告诉系统,我是独一无二的,2.告诉任务栈我是独一无二的,也就是说,任务栈中除了我不能再有其他Activity。

所以,如果要启动singleInstance模式的Activity,那只能新创建一个任务栈用来放它,因为人家说了,“我是独一无二的!”。同样的,如果从这种启动模式的Activity中启动别的Activity,那不好意思,我不管你是不是和我处在同一个应用,我所在的任务栈只能拥有我一个人,您呐,另外让系统给你创建一个任务栈待着去吧。

三、启动模式的使用

3.1 在AndroidManifest.xml文件中配置

                                                                      

3.2 通过Intent添加标志来识别

Intent intent = new Intent(this,MainActivity.class);        intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);     // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        startActivity(intent);

常用的Flag

  • INTENT.FLAG_ACTIVITY_NEW_TASK

启动一个Activity,但是启动的每个Activity都将在一个全新的Task中。该Flag通常用来从Service中启动Activity的场景,由于在Service中并不存在Activity栈,所以使用该Flag来创建一个新的Activity栈,并创建新的Activity实例。

  • INTENT.FLAG_ACTIVITY_SINGLE_TOP

等同于android:launchMode=“singleTop”

  • INTENT.FLAG_ACTIVITY_CLEAR_TOP

    等同于android:launchMode=“singleTask”

  • INTENT.FLAG_ACTIVITY_NO_HISTORY

使用这种模式启动Activity,当该Activity启动其他Activity后,该Activity就消失了,不会保留在Activity栈中,例如A-B,B以这种模式启动C,C在启动D,则当前Activity栈为ABD。

文章写到这,希望对给位有所帮助,谢谢观看。

参考文献:
https://www.jianshu.com/p/4c8d6e2117ac
http://blog.csdn.net/x283930450/article/details/70597555

更多相关文章

  1. android五种布局模式
  2. Android(安卓)MTP之服务端UsbService启动
  3. [camera drv]工厂模式下测试camera fail
  4. Android(安卓)studio 启动模拟器时解决 VT-x is disabled in BIO
  5. MVVM模式开源学习项目——玩Android客户端
  6. android recovery 模式启动进入流程
  7. Android中onResume()的启动执行顺序
  8. Android输入管理_InputManager服务启动
  9. Android(安卓)中文 API (101) —— AsyncTask

随机推荐

  1. android 5.0多用户支持
  2. Android中做一个无标题窗口
  3. Android不依赖Activity的全局悬浮窗实现
  4. 使用eclipse打开android_sdk自带的例子
  5. android之照相、相冊裁剪功能的实现过程
  6. Android(安卓)实现全屏显示的几种方法整
  7. Android(安卓)Theme的设置
  8. android中调试之日志
  9. android sdk setup时出现:Failed to fetc
  10. Android(安卓)XML解析