zoukankan      html  css  js  c++  java
  • Activity的LaunchMode

    Activity的LaunchMode

    Tasks和Back Stack

    • 一个Task表示与用户的一次交互,包含交互过程中的多个Activity实例。当用户通过点击桌面上的Launcher图标打开一个app时,则启动一个新的Task开始与用户交互,当用户点击Home键时,当前Task则被转入后台,而当用户再次点击桌面上相同的Launcher图标时则将刚才转入后台的Task转入前台与用户交互。

    • 每个Task使用一个Back Stack来管理这些Activity实例,栈顶是当前与用户交互的Activity,由当前Activity启动另一个Activity后,则新启动的Activity压入栈顶。如果用户使用Back键返回上一个Activity,则弹出栈顶Activity。

    • 一个Task中可能涉及多个App中的Activity,因为一次交互可能会涉及多个App的协作,一个App也可能使用多个Task与用户交互。一个Task与App的一次运行并不是一一对应的关系。

    Activity的几种LaunchMode

    由一个Activity启动另一个Activity通常使用Intent,然后调用startActivity(Intent)方法。

    假设需要启动的是ActivityA,对于ActivityA有以下几种启动模式:

    • standard模式
        默认的模式,即总是为ActivityA创建一个新的实例并压入当前Task的Back Stack栈顶。当前Task的Back Stack中可能存在多个此ActivityA的实例。

    • singleTop模式
        若当前Task的Back Stack栈顶不是ActivityA的实例,则创建一个新的ActivityA实例并压入栈顶,若当前Task的Back Stack栈顶已经是ActivityA的实例则不再创建新的实例,而是直接启动栈顶ActivityA实例并通过onNewIntent方法传入Intent对象(onNewIntent方法会在onResume方法之前被调用)。

    • singleTask模式
        若某个Task(若该Task位于后台,则转入前台)的Back Stack栈已经包含ActivityA的实例,则不再创建新的实例,而是直接启动已经存在的ActivityA的实例并通过onNewIntent方法传入Intent对象,此种情况下,若已经存在的ActivityA实例不在Back Stack的栈顶,则弹出ActivityA实例之上的所有Activity使得ActivityA的实例位于栈顶。
        若没有Task包含ActivityA的实例,则创建一个新的ActivityA实例,并启动一个新的Task(实际上不一定总是启动新的Task)来保存新创建的ActivityA实例。
        使用singleTask模式启动ActivityA,则始终只有一个ActivityA的实例。

    • singleInstance模式
        与singleTask模式基本一样,在没有Task包含ActicityA的实例情况下,会启动一个新的Task来保存新创建的AcitivityA实例,不同的是该新启动的Task将始终只包含ActivityA的唯一实例,不会再包含其他Activity实例。
        使用singleInstance模式启动ActivityA,则始终只有一个ActivityA实例,并且此ActivityA实例独占一个Task。

    关于singleTask模式的说明

      上面说在没有Task包含ActivityA实例的情况下,会启动一个新的Task来保存新创建的ActivityA实例,实际上并不一定如此。Activity还有一个taskAffinity属性,用来声明该Activity倾向于保存在哪个Task中,属于同一个app的Activity默认拥有相同的taskAffinity。
      在singleTask模式没有Task包含ActivityA实例的情况下,系统会先寻找是否存在与ActivityA拥有相同taskAffinity的ActivityB实例,若找到了则将新创建的ActivityA实例保存在ActivityB实例所在的Task中,找不到的情况下才会启动一个新的Task。因此,如果当前启动ActivityA的Activity和ActivityA属于同一个app,则新创建的ActivityA实例仍保存在当前Task。


    Intent启动Activity的Flag

      除了在AndroidManifest.xml文件中配置Activity的LaunchMode,也可以在使用Intent启动Activity时设置Flag来达到相同的效果,并且当这两种方式设置的启动模式有冲突时,系统优先采用Intent设置Flag的方式。

    • FLAG_ACTIVITY_NEW_TASK
        此Flag与singleTask模式基本相似(而且启动新Task也需要参考taskAffinity属性),所不同的是使用FLAG_ACTIVITY_NEW_TASK不会弹出ActivityA实例之上的所有其他Acticity实例。
        此Flag通常配合其他Flag一起使用,配合FLAG_ACTIVITY_CLEAR_TOP时则与singleTask模式相同。

    • FLAG_ACTIVITY_SINGLE_TOP
      此Flag与singleTop模式相同

    • FLAG_ACTIVITY_CLEAR_TOP
        使用此Flag来启动ActivityA实例时,若当前Task中已经存在ActivityA的实例,则不再创建ActivityA的实例,并弹出ActivityA实例之上的其他Activity使得ActivityA实例位于栈顶。若当前Task不存在ActivityA的实例则创建新的实例并入栈。
        此Flag通常配合FLAG_ACTIVITY_NEW_TASK一起使用,当配合FLAG_ACTIVITY_NEW_TASK一起使用时则与singTask模式相同。

    • FLAG_ACTIVITY_MULTI_TASK
        使用此Flag来启动ActivityA实例时,总是启动一个新的Task来包含创建的ActivityA实例。
        需要注意的是单独使用此Flag没有效果,此Flag必须与FLAG_ACTIVITY_NEW_TASK或者FLAG_ACTIVITY_NEW_DOCUMENT配合使用。
    • FLAG_ACTIVITY_NEW_DOCUMENT
        此Flag通常配合FLAG_ACTIVITY_MULTI_TASK一起使用,这样在多个ActivityA实例中打开多个document时,对于每个document都会启动一个Task,并且在Overview Screen中每个document都对应一个Task缩略图。

      document表示app希望同时维护多个实例的组件,比如:文本文件(同时编辑多个doc文件)、网页(多Tab形式)、邮件等。
      对于这些document组件,通常每次创建一个Activity实例去维护时都希望在一个新的Task中保存创建的Activity实例,以避免编辑状态被其他Activity实例所破坏。此时就可以使用FLAG_ACTIVITY_NEW_DOCUMENT配合FLAG_ACTIVITY_MULTI_TASK来达到效果。当然还有其他的documentLaunchMode来用于控制如何创建Activity实例维护这些document,不作展开。
      当FLAG_ACTIVITY_MULTI_TASK配合FLAG_ACTIVITY_NEW_TASK或者FLAG_ACTIVITY_NEW_DOCUMENT使用时都会每次启动新的Task来保存创建的Activity实例。不同的是与前者配合时,虽然启动了多个Task,但在Overview Screen中只有一个Task缩略图;而与后者配合使用时,启动的每个Task在Overview Screen中都有一个对应的Task缩略图,这样用户可以方便的点击Task缩略图来选择继续维护某个document的状态。

     
     
  • 相关阅读:
    Hologres如何支持亿级用户UV计算
    飞猪基于 Serverless 的云+端实践与思考
    高德打车构建可观测性系统实践
    程序员写好技术文章的几点小技巧
    配置审计(Config)变配报警设置
    进入中国内地第31年的麦当劳 ,为什么还能不断吸引新消费人群?
    OceanBase再破纪录!核心成员陈萌萌:坚持HTAP就是坚持我们做数据库的初心
    找出有序数组中缺失的数字
    删除值重复的结点
    想交链表----若有缘 必相见
  • 原文地址:https://www.cnblogs.com/jqctop1/p/5430030.html
Copyright © 2011-2022 走看看