zoukankan      html  css  js  c++  java
  • Activity的启动模式全解standard,singleTop,singleTask,singleInstance

    在android中控制Activity的启动模式的属性主要控制两大功能:

    1,控制activity 进入哪一个任务task 中,   有两种可能,进入启动task中,进入指定taskAffinity的task中,如果指定taskAffinity的task还不存在,则创建一个

    2,控制activity 多次启动的处理模式,       有三种可能,每次都创建新的,如果在顶部不创建新的,  如果存在则清除之上所有的activity

    activity的taskAffinity属性值默认为application的taskAffinity属性值,application的taskAffinity属性值默认为包名 

    手动设置taskAffinity属性值时,可以设置任意字符串但是必须包含至少一个'.'点符号,否则apk会在安装时解析包错误

    Activity的启动模式中多次启动的处理模式要先确定activity进入的task

    activity 的launchMode 静态设置时有四种模式,动态设置(intent flag)时常用的有三种 ,其中让taskAffinity属性起作用的有两种模式 singleTaskFLAG_ACTIVITY_NEW_TASK ,其他launchMode启动模式taskAffinity属性无效 

    • launchMode      standard      进入启动task,每次都创建新的实例进入task顶部

                              singleTop    进入启动task,如果已有实例并且在task顶部不创建新实例,调用原实例的onNewIntent(),其它情况都创建新的实例进入task顶部

      •                singleTask   进入指定taskAffinity的task,如果指定的task存在,将task移到前台,如果指定task不存在,创建指定taskAffinity的task
      •                                    如果task中存在实例,则移除实例之上的所有实例并显示出来,执行原实例的onNewIntent(),其它情况则创建实例进入task顶部
      •               singleInstance   进入新的task,并且此task内只存在此一个activity ,不再加入别的activity
      •                                          如果task中存在实例,执行实例的onNewIntent()                  
    • taskAffinity起作用时:       进入指定taskAffinity的task,如果指定的task存在,将task移到前台,如果指定task不存在,创建指定taskAffinity的task 

                                    

    而在Intent当中,flag属性控制activity的启动模式:

         FLAG_ACTIVITY_NEW_TASK    进入指定taskAffinity的task,如果指定的task存在,将task移到前台,如果指定task不存在,创建指定taskAffinity的task                                                          

                                                          每次都创建新的实例进入task顶部

         FLAG_ACTIVITY_SINGLE_TOP   进入启动task

                                                             如果已有实例并且在task顶部不创建新实例,执行实例的onNewIntent(),其它情况都创建新的实例进入task顶部

         FLAG_ACTIVITY_CLEAR_TOP    进入启动task

                                                             如果task中存在实例,则移除实例之上的所有实例,如果启动的activity启动模式不是standard模式,或者flag有FLAG_ACTIVITY_SINGLE_TOP属性

                                                             那么调用Activity B的onNewIntent()方法否则销毁原有实例创建新实例进入task顶部,其它情况则创建实例进入task顶部

    对activity的启动模式属性中Intent的flag属性覆盖<activity>元素中属性设置;

    在<activity>元素中,有以下几个属性是可以使用的:

    • taskAffinity
    • launchMode
    • allowTaskReparenting
    • clearTaskOnLaunch
    • alwaysRetainTaskState
    • finishOnTaskLaunch

    而在Intent当中,有以下几个flag是比较常用的:

    • FLAG_ACTIVITY_NEW_TASK
    • FLAG_ACTIVITY_CLEAR_TOP
    • FLAG_ACTIVITY_SINGLE_TOP

    处理affinity

     

    affinity可以用于指定一个Activity更加愿意依附于哪一个任务,在默认情况下,同一个应用程序中的所有Activity都具有相同的affinity,所以,这些Activity都更加倾向于运行在相同的任务当中。当然了,你也可以去改变每个Activity的affinity值,通过<activity>元素的taskAffinity属性就可以实现了。

    taskAffinity属性接收一个字符串参数,你可以指定成任意的值(经我测试字符串中至少要包含一个.),但必须不能和应用程序的包名相同,因为系统会使用包名来作为默认的affinity值。

    affinity主要有以下两种应用场景:

    • 当调用startActivity()方法来启动一个Activity时,默认是将它放入到当前的任务当中。但是,如果在Intent中加入了一个FLAG_ACTIVITY_NEW_TASK flag的话(或者该Activity在manifest文件中声明的启动模式是"singleTask"),系统就会尝试为这个Activity单独创建一个任务。但是规则并不是只有这么简单,系统会去检测要启动的这个Activity的affinity和当前任务的affinity是否相同,如果相同的话就会把它放入到现有任务当中,如果不同则会去创建一个新的任务。而同一个程序中所有Activity的affinity默认都是相同的,这也是前面为什么说,同一个应用程序中即使声明成"singleTask",也不会为这个Activity再去创建一个新的任务了。
    • 当把Activity的allowTaskReparenting属性设置成true时,Activity就拥有了一个转移所在任务的能力。具体点来说,就是一个Activity现在是处于某个任务当中的,但是它与另外一个任务具有相同的affinity值,那么当另外这个任务切换到前台的时候,该Activity就可以转移到现在的这个任务当中。
      那还是举一个形象点的例子吧,比如有一个天气预报程序,它有一个Activity是专门用于显示天气信息的,这个Activity和该天气预报程序的所有其它Activity具体相同的affinity值,并且还将allowTaskReparenting属性设置成true了。这个时候,你自己的应用程序通过Intent去启动了这个用于显示天气信息的Activity,那么此时这个Activity应该是和你的应用程序是在同一个任务当中的。但是当把天气预报程序切换到前台的时候,这个Activity又会被转移到天气预报程序的任务当中,并显示出来,因为它们拥有相同的affinity值,并且将allowTaskReparenting属性设置成了true。

    清空返回栈

    如何用户将任务切换到后台之后过了很长一段时间,系统会将这个任务中除了最底层的那个Activity之外的其它所有Activity全部清除掉。当用户重新回到这个任务的时候,最底层的那个Activity将得到恢复。这个是系统默认的行为,因为既然过了这么长的一段时间,用户很有可能早就忘记了当时正在做什么,那么重新回到这个任务的时候,基本上应该是要去做点新的事情了。

    当然,既然说是默认的行为,那就说明我们肯定是有办法来改变的,在<activity>元素中设置以下几种属性就可以改变系统这一默认行为:

    alwaysRetainTaskState

    如果将最底层的那个Activity的这个属性设置为true,那么上面所描述的默认行为就将不会发生,任务中所有的Activity即使过了很长一段时间之后仍然会被继续保留。

    clearTaskOnLaunch

    如果将最底层的那个Activity的这个属性设置为true,那么只要用户离开了当前任务,再次返回的时候就会将最底层Activity之上的所有其它Activity全部清除掉。简单来讲,就是一种和alwaysRetainTaskState完全相反的工作模式,它保证每次返回任务的时候都会是一种初始化状态,即使用户仅仅离开了很短的一段时间。

    finishOnTaskLaunch

    这个属性和clearTaskOnLaunch是比较类似的,不过它不是作用于整个任务上的,而是作用于单个Activity上。如果某个Activity将这个属性设置成true,那么用户一旦离开了当前任务,再次返回时这个Activity就会被清除掉。

  • 相关阅读:
    协方差矩阵
    SLAM中的关键帧是什么?有什么用?如何选择关键帧?
    EKF算法与非线性优化算法的比较
    LC217 存在重复元素
    LC42 接雨水
    LC20 有效的括号
    LC3 无重复最长子串
    LC4 寻找两个有序数组的中位数
    ubuntu16.04下安装g2o
    小米 各版本手机系统包 线刷包 卡刷包
  • 原文地址:https://www.cnblogs.com/ldq2016/p/6893471.html
Copyright © 2011-2022 走看看