美文网首页
Activity启动模式

Activity启动模式

作者: 小杨不想努力了 | 来源:发表于2022-01-21 00:01 被阅读0次

Android提供了四种Activity启动方式:

  1. 标准模式(standard)

  2. 栈顶复用模式(singleTop)

  3. 栈内复用模式(singleTask)

  4. 单例模式(singleInstance)

    Activity的管理是采用任务栈的形式,任务栈采用“后进先出”的栈结构。

    标准模式:

    该模式也是系统的默认模式,当我们多次创建Activity时,系统会将创建的实例一一放入任务栈,不管它是否已经被创建过。该模式下,谁启动了这个Activity,它就运行在启动的它的Activity所在的栈中。

    例如:Activity A启动了Activity B,则就会在A所在的栈顶压入一个新的Activity。
    特殊情况,如果在Service或Application中启动一个Activity,其并没有所谓的任务栈,可以使用标记位Flag来解决。解决办法:为待启动的Activity指定FLAG_ACTIVITY_NEW_TASK标记位,创建一个新栈。

    应用场景: 绝大多数Activity。如果以这种方式启动的Activity被跨进程调用,在5.0之前新启动的Activity实例会放入发送Intent的Task的栈的顶部,尽管它们属于不同的程序,这似乎有点费解看起来也不是那么合理,所以在5.0之后,上述情景会创建一个新的Task,新启动的Activity就会放入刚创建的Task中,这样就合理的多了。

    栈顶复用模式:

    顾名思义,在这种模式下,如果有新的Activity已经存在任务栈的栈顶,那么此Activity就不会被重新创建新实例,而是复用已存在任务栈栈顶的Activity,并回调如下方法:

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
    }
    //通过此方法的参数,我们可以获取当前请求的相关信息,此时Activity的onCreate、onStart方法不会被调用,因为Activity并没有被重建。
    

    ps:如果栈顶不是新建的Activity,就会创建该Activity新的实例,并放入栈顶。

    应用场景:这种模式通常比较适用于接收到消息后显示的界面,比如在通知栏点击收到的通知,然后需要启动一个Activity,这个Activity就可以用singleTop,否则每次点击都会新建一个Activity。当然实际的开发过程中,测试妹纸没准给你提过这样的bug:某个场景下连续快速点击,启动了两个Activity。如果这个时候待启动的Activity使用singleTop模式也是可以避免这个Bug的。同standard模式,如果是外部程序启动singleTop的Activity,在Android 5.0之前新创建的Activity会位于调用者的Task中,5.0及以后会放入新的Task中。

    栈内复用模式:
    该模式是一种单例模式,即一个栈内只有一个该Activity实例。该模式,可以通过在AndroidManifest文件的Activity中指定该Activity需要加载到那个栈中,即singleTask的Activity可以指定想要加载的目标栈。singleTask和taskAffinity配合使用,指定开启的Activity加入到哪个栈中。

    <activity android:name=".Activity1"
        android:launchMode="singleTask"
        android:taskAffinity="com.lvr.task"
        android:label="@string/app_name">
    </activity>
    

    关于taskAffinity的值: 每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task。如果一个Activity没有显式的指明该Activity的taskAffinity,默认为应用的包名。

    执行逻辑:

    在这种模式下,如果Activity指定的栈不存在,则创建一个栈,并把创建的Activity压入栈内。如果Activity指定的栈存在,如果其中没有该Activity实例,则会创建Activity并压入栈顶,如果其中有该Activity实例,则把该Activity实例之上的Activity杀死清除出栈,重用并让该Activity实例处在栈顶,然后调用 onNewIntent()方法。

    应用场景: 大多数App的主页(频繁使用的主架构)。对于大部分应用,当我们在主界面点击回退按钮的时候都是退出应用,那么当我们第一次进入主界面之后,主界面位于栈底,以后不管我们打开了多少个Activity,只要我们再次回到主界面,都应该使用将主界面Activity上所有的Activity移除的方式来让主界面Activity处于栈顶,而不是往栈顶新加一个主界面Activity的实例,通过这种方式能够保证退出应用时所有的Activity都能报销毁。在跨应用Intent传递时,如果系统中不存在singleTask Activity的实例,那么将创建一个新的Task,然后创建SingleTask Activity的实例,将其放入新的Task中。

    单实例模式:

    作为栈内复用模式的加强版,打开该Activity时,直接创建一个新的任务栈,并创建该Activity实例放入新栈中。一旦该模式的Activity实例已经存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例。

    应用场景:这个经常使用于系统中的应用,比如Launch、锁屏键、来电显示等等,整个系统中仅仅有一个呼叫来电界面。这种模式的使用情况比较罕见,在Launcher中可能使用。或者你确定你需要使Activity只有一个实例。

    启动模式的使用方式

    1. 在 Manifest.xml中指定Activity启动模式

      一种静态的指定方法,在Manifest.xml文件里声明Activity的同一时候指定它的启动模式,这样在代码中跳转时会依照指定的模式来创建Activity。样例以下:

      <activity
      android:launchMode="启动模式"
      //属性
      //standard:标准模式
      //singleTop:栈顶复用模式
      //singleTask:栈内复用模式
      //singleInstance:单例模式
      //如不设置,Activity的启动模式默认为**标准模式(standard)**
      </activity>
      
    2. 启动Activity时。在Intent中指定启动模式去创建Activity一种动态的启动模式,在new 一个Intent后,通过Intent的addFlags方法去动态指定一个启动模式。样例以下:

      Intent intent = new Intent();      
      intent.setClass(context, MainActivity.class);       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
      startActivity(intent);     
      

    注意:以上两种方式都能够为Activity指定启动模式,可是二者还是有差别的。

    • 优先级:动态指定方式即第二种比第一种优先级要高,若两者同一时候存在,以第二种方式为准。
    • 限定范围:第一种方式无法为Activity直接指定 FLAG_ACTIVITY_CLEAR_TOP 标识,第二种方式无法为 Activity指定 singleInstance 模式。

    Activity 的 Flags

    标记位既能够设定Activity的启动模式,如同上面介绍的,在动态指定启动模式:比方 FLAG_ACTIVITY_NEW_TASK 和 FLAG_ACTIVITY_SINGLE_TOP 等。它还能够影响Activity 的运行状态 ,比方 FLAG_ACTIVITY_CLEAN_TOP 和 FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 等。

    1. FLAG_ACTIVITY_NEW_TASK

      作用是为Activity指定 “SingleTask”启动模式。跟在AndroidMainfest.xml指定效果同样。

    2. FLAG_ACTIVITY_SINGLE_TOP

      作用是为Activity指定 “SingleTop”启动模式,跟在AndroidMainfest.xml指定效果同样。

    3. FLAG_ACTIVITY_CLEAN_TOP

      具有此标记位的Activity,当它启动时,在同一个任务栈中所有位于它上面的Activity都要出栈。如果和singleTask模式一起出现,若被启动的Activity已经存在栈中,则清除其之上的Activity,并调用该Activity的onNewIntent()方法。如果被启动的Activity采用standard模式,那么该Activity连同之上的所有Activity出栈,然后创建新的Activity实例并压入栈中。

    4. FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

      具有此标记位的Activity不会出如今历史Activity的列表中,使用场景:当某些情况下我们不希望用户通过历史列表回到Activity时,此标记位便体现了它的效果。它等同于在xml中指定Activity的属性:

      android:excludeFromRecents=“trure”

相关文章

网友评论

      本文标题:Activity启动模式

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