美文网首页Android
Activity 启动模式LaunchMode

Activity 启动模式LaunchMode

作者: 敏捷Studio | 来源:发表于2019-12-17 11:54 被阅读0次

    准备知识

    • 为什么需要启动模式
      在Android开发中,我们都知道,在默认的情况下,如果我们启动的是同一个Activity的话,系统会创建多个实例并把它们一一放入任务栈中。当我们点击返回(back)键,这些Activity实例又将从任务栈中一一移除,遵循的原则是“后进先出”(先进后出)。
      这里我们考虑一个问题,当我们多次启动同一个Activity,系统也会创建多个实例放入任务栈中,这样岂不是很耗费内存资源?为了解决这一问题,Android为Actiivty提供了启动模式。

    • 启动模式
      Activity的启动模式有四种:standardsingleTopsingleTasksingleInstance

    • 如何使用

      <activity
         android:name=".DemoActivity"
         <!-- value 可以设为启动模式中任意一种,默认standard -->
         android:launchMode="singleTop" >
      </activity>
      

    启动模式的分类

    标准模式:standard

    • 这种启动模式为标准模式,也是默认模式
    • 每当我们启动一个Activity,系统就会相应的创建一个实例,不管这个实例是否已经存在
    • 这种模式,一个栈中可以有多个实例,每个实例也都有自己的任务栈。而且是谁启动了此Activity,那么这个Activity就运行在启动它的Activity所在的栈中。
    • 【跨进程】这种方式启动的Activity被跨进程调用
      • 系统5.0之前:新启动的Activity实例会放入发送Intent的Task的栈的顶部,尽管它们属于不同的程序,这似乎有点费解看起来也不是那么合理
      • 系统5.0之后:上述情景会创建一个新的Task,新启动的Activity就会放入刚创建的Task中,这样就合理的多了

    栈顶复用模式:singleTop

    • 当前栈中不存在该Activity的实例时:其行为同standard启动模式
    • 当前栈中已有该Activity的实例并且该实例位于栈顶时:不会创建实例,而是复用栈顶的实例,并且会将Intent对象传入,回调onNewInten()方法
    • 当前栈中已有该Activity的实例但是该实例不在栈顶时:其行为和standard启动模式一样,依然会创建一个新的实例
    • 【跨进程】这种方式启动的Activity被跨进程调用表现同standard

    栈内复用模式:singleTask

    在复用的时候,首先会根据taskAffinity去找对应的任务栈:

    • 如果不存在指定的任务栈,系统会新建对应的任务栈,并新建Activity实例压入栈中
    • 如果存在指定的任务栈,则会查找该任务栈中是否存在该Activity实例
      a、如果不存在该实例,则会在该任务栈中新建Activity实例
      b、如果存在该实例,则会直接引用,并且回调该实例的onNewIntent()方法。并且任务栈中该实例之上的Activity会被全部销毁
    • 【跨进程】这种方式启动的Activity被跨进程调用表现同standard

    单实例模式:singleInstance

    该实例为系统唯一,不同的应用去打开这个activity 共享公用的同一个activity。他会运行在自己单独,独立的任务栈里面,并且任务栈里面只有他一个实例存在。启动该模式Activity的时候,会查找系统中是否存在:

    • 不存在,首先会新建一个任务栈,其次创建该Activity实例
    • 存在,则会直接引用该实例,并且回调onNewIntent()方法

    LaunchMode Flag

    Activity 的启动模式除了在 AndroidManifest 文件中设置以外,还可以通过 Intent的 Flag 来设置:

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

    • FLAG_ACTIVITY_SINGLE_TOP
      使用 singletop 模式启动一个Activity, 当这个Activity位于历史stack的顶端运行时,不再创建一个新的Activity实例;
      与指定android:launchMode=“singleTop”效果相同

    • FLAG_ACTIVITY_CLEAR_TOP
      销毁目标Activity和它之上的所有Activity,重新创建目标Activity
      与指定android:launchMode=“singleTask”效果相同

    • FLAG_ACTIVITY_NO_HISTORY
      一个 Activity 使用这种模式启动后,当该 Activity 启动其他Activity后,该 Activity 自己就消失了,不会保留在Activity栈中。

    • FLAG_ACTIVITY_BROUGHT_TO_FRONT
      在launchMode中设置singleTask模式时系统会设定。

    • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
      如果设置,新的Activity不会在最近启动的Activity的列表中保存。

    • FLAG_ACTIVITY_FORWARD_RESULT
      如果设置,并且这个Intent用于从一个存在的Activity启动一个新的Activity,那么,这个作为答复目标的Activity将会传到这个新的Activity中。这种方式下,新的Activity可以调用setResult(int),并且这个结果值将发送给那个作为答复目标的 Activity。

    • FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
      这个标志一般不由应用程序代码设置,如果这个Activity是从历史记录里启动的(常按HOME键),系统会设定。

    任务栈

    任务栈Task,是一种用来放置Activity实例的容器,他是以栈的形式进行盛放,也就是所谓的先进后出,主要有2个基本操作:压栈和出栈,其所存放的Activity是不支持重新排序的,只能根据压栈和出栈操作更改Activity的顺序。

    启动一个Application的时候,系统会为它默认创建一个对应的Task,用来放置根Activity。默认启动Activity会放在同一个Task中,新启动的Activity会被压入启动它的那个Activity的栈中,并且显示它。当用户按下回退键时,这个Activity就会被弹出栈,按下Home键回到桌面,再启动另一个应用,这时候之前那个Task就被移到后台,成为后台任务栈,而刚启动的那个Task就被调到前台,成为前台任务栈,Android系统显示的就是前台任务栈中的Top实例Activity。

    相关文章

      网友评论

        本文标题:Activity 启动模式LaunchMode

        本文链接:https://www.haomeiwen.com/subject/vrfdnctx.html