美文网首页
Activity-四种启动模式及使用方法

Activity-四种启动模式及使用方法

作者: 林锦洲 | 来源:发表于2019-01-17 12:02 被阅读126次

    一、任务栈(或叫回退栈)

    说到Activity的启动模式,必须先了解Activity的任务栈。

    • android任务栈又称为Task,它是一个栈结构,具有"先进后出,后进先出"的特性,用于存放我们的Activity组件。
    • 我们每次打开一个新的Activity或者退出当前Activity都会在任务栈中添加或者减少一个Activity,因此一个任务栈包含了一个Activity的集合, android系统可以通过任务栈有序地管理每个Activity,并决定哪个Activity与用户进行交互:只有在任务栈栈顶的Activity才可以跟用户进行交互。
    • 在我们退出应用程序时,必须把所有的任务栈中所有的Activity清除出栈时,任务栈才会被销毁。当然任务栈也可以移动到后台, 并且保留了每一个Activity的状态. 可以有序的给用户列出它们的任务, 同时也不会丢失Activity的状态信息。 任务栈的前台后台
    • 需要注意的是,一个App中可能不止一个任务栈,某些特殊情况下,单独一个Actvity可以独享一个任务栈。还有一点就是一个任务栈中的Actvity可以来自不同的App,同一个App的Activity也可能不在一个任务栈中。
    • 任务栈最后一个Activity被销毁时,对应的应用程序被关闭,清除任务栈,但是还会保留应用程序进程(狂点Back退出到Home界面后点击Menu会发现还有这个App的框框。个人理解应该是这个意思),再次点击进入应用会创建新的任务栈

    二、四种启动模式

    1、standard标准模式
    Standard模式是Android的默认启动模式,你不在配置文件中做任何设置,那么这个Activity就是standard模式,这种模式下,Activity可以有多个实例,每次启动Activity,无论任务栈中是否已经有这个Activity的实例,系统都会创建一个新的Activity实例。 standard模式
    2、singleTop栈顶复用模式
    SingleTop模式和standard模式非常相似,主要区别就是当一个singleTop模式的Activity已经位于任务栈的栈顶,再去启动它时,不会再创建新的实例,如果不位于栈顶,就会创建新的实例。 singletop模式
    3、singleTask栈内复用模式
    SingleTask模式的Activity在同一个Task内只有一个实例,如果Activity已经位于栈顶,系统不会创建新的Activity实例,和singleTop模式一样。但Activity已经存在但不位于栈顶时,系统就会把该Activity移到栈顶,并把它上面的activity出栈。 singletask模式
    4、singleInstance单实例模式
    singleInstance模式也是单例的,但和singleTask不同,singleTask只是任务栈内单例,系统里是可以有多个singleTask Activity实例的,而singleInstance Activity在整个系统里只有一个实例,启动一singleInstanceActivity时,系统会创建一个新的任务栈,并且这个任务栈只有他一个Activity。比如,A应用需要启动的MainActivity 是singleInstance模式,当A启动后,系统会为它创建一个新的任务栈,然后A单独在这个新的任务栈中,如果此时B应用也要激活MainActivity,由于栈内复用的特性,则不会重新创建,而是两个应用共享一个Activity的实例。SingleInstance模式并不常用,如果我们把一个Activity设置为singleInstance模式,你会发现它启动时会慢一些,切换效果不好,影响用户体验。它往往用于多个应用之间,例如一个电视launcher里的Activity,通过遥控器某个键在任何情况可以启动,这个Activity就可以设置为singleInstance模式,当在某应用中按键启动这个Activity,处理完后按返回键,就会回到之前启动它的应用,不影响用户体验。 singleinstance模式

    三、两种启动模式的使用方式

    1、在 Manifest.xml中指定Activity启动模式(静态设置)

    在Manifest.xml文件里声明Activity的同时,在launchMode里指定它的启动模式。

     <activity android:name=".StandardActivity" android:launchMode="standard"/>
     <activity android:name=".SingleTop2Activity" android:launchMode="singleTop"/>
     <activity android:name=".SingleTaskActivity" android:launchMode="singleTask"/>
     <activity android:name=".SingleInstanceActivity" android:launchMode="singleInstance"/>
    
    2、启动Activity时。在Intent中指定启动模式去创建Activity(动态设置)

    在new 一个Intent后,通过Intent的addFlags()方法去动态指定一个启动模式。

    Intent intent = new Intent();
    intent.setClass(context, MainActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(intent);
    
    注:如果同时有动态和静态设置,那么动态的优先级更高。

    四、Activity常用的Flags

    因为Activity的Flag比较多,切勿死记,我们知道一些常用的就够了,须要时再查官方文档

    • Intent.FLAG_ACTIVITY_NEW_TASK

    该标志位表示使用singleTask模式来启动一个Activity,与在清单文件指定android:launchMode="singleTask"效果相同。

    • Intent.FLAG_ACTIVITY_SINGLE_TOP

    该标志位表示使用singleTop模式来启动一个Activity,与在清单文件指定android:launchMode="singleTop"效果相同。

    • Intent.FLAG_ACTIVITY_CLEAR_TOP

    具有此标记位的Activity,启动时会将与该Activity在同一任务栈的其他Activity出栈。一般与SingleTask启动模式一起出现。它会完毕SingleTask的作用。但事实上SingleTask启动模式默认具有此标记位的作用

    • Intent.FLAG_ACTIVITY_NO_HISTORY

    使用该模式来启动Activity,当该Activity启动其他Activity后,该Activity就被销毁了,不会保留在任务栈中。如A-B,B中以这种模式启动C,C再启动D,则任务栈只有ABD。

    • Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

    使用该标识位启动的Activity不添加到最近应用列表,也即我们从最近应用里面查看不到我们启动的这个activity。与属性android:excludeFromRecents="true"效果相同。

    五、启动模式与StartActivityForResult的一个坑

    我们在开发过程中经常会用到StartActivityForResult方法启动一个Activity,然后在onActivityResult()方法中可以接收到上个页面的回传值,但你有可能遇到过拿不到返回值的情况,那有可能是因为Activity的LaunchMode设置为了singleTask。5.0之后,android的LaunchMode与StartActivityForResult的关系发生了一些改变。两个Activity,A和B,现在由A页面跳转到B页面,看一下LaunchMode与StartActivityForResult之间的关系:


    5.0之前 5.0之后

    这是因为ActivityStackSupervisor类中的startActivityUncheckedLocked方法在5.0中进行了修改。在5.0之前,当启动一个Activity时,系统将首先检查Activity的launchMode,如果为A页面设置为SingleInstance或者B页面设置为singleTask或者singleInstance,则会在LaunchFlags中加入FLAG_ACTIVITY_NEW_TASK标志,而如果含有FLAG_ACTIVITY_NEW_TASK标志的话,onActivityResult将会立即接收到一个cancle的信息,而5.0之后这个方法做了修改,修改之后即便启动的页面设置launchMode为singleTask或singleInstance,onActivityResult依旧可以正常工作,也就是说无论设置哪种启动方式,StartActivityForResult和onActivityResult()这一组合都是有效的。所以如果你目前正好基于5.0做相关开发,不要忘了向下兼容,这里有个坑请注意避让。

    相关文章

      网友评论

          本文标题:Activity-四种启动模式及使用方法

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