Activity启动模式及任务栈

前言

在默认情况下,每当我们启动一个Activity,Android系统都会为我们创建一个新的实例并将其加入任务栈中。如果多次启动同一个Activity,任务栈就会存在多个相同的实例。这样做显然是不够高效的,因此Android为Activity提供了多种启动模式。在具体的场景下选用合适的启动模式,可以大大提高应用性能。

Activity启动模式

standard

标准模式。这是Activity默认的启动模式,每次启动Activity都会生成一个新的实例。通过这种方式启动的Activity实例,默认会被添加到启动它的Activity所在的任务栈中。

singleTop

栈顶复用模式。如果被启动的Activity实例已经位于任务栈栈顶,则不会再创建新的实例,该Activity的onNewIntent方法将被调用。否则,依旧会创建新的Activity实例。

singleTask

栈内复用模式。如果被启动的Activity实例已经存在于任务栈内,则不会创建新的实例。Android系统将会把该Activity实例之上的其它Activity出栈,然后回调这个Activity的onNewIntent方法。需要注意的是,如果在AndroidManifest中为被启动的Activity指定了独有的taskAffinity属性,则Activity将会在指定的的任务栈中创建。如果这个任务栈不存在,则会先创建这个任务栈。具体细节请参考后文任务栈部分。

singleInstance

单实例模式。这是一种加强型的singleTask模式。这种启动模式不仅拥有singleTask的所有特性,还确保Activity实例将会在一个独有的任务栈创建。换句话说,指定了这种启动模式的Activity实例将独享一个任务栈。只要在这个任务栈中存在该Activity的实例,后续启动这个Activity就不会创建新的实例了,只会调用它的onNewIntent方法。否则,Android系统会先创建任务栈,然后在该任务栈中创建这个Activity的实例。

任务栈

任务栈是一种“先进后出”的数据结构,负责存储Activity的实例。默认情况下,所有Activity的任务栈名都和它的应用包名相同。但是,我们可以通过在AndroidManifest文件中为Activity指定taskAffinity属性,为Activity指定其他的任务栈名。如下所示:

  <activity
        android:name=".MainActivity"
          android:taskAffinity="com.codingending.newtask">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
  </activity>

需要注意,taskAffinity不能指定为应用包名,否则相当于没有指定。此外,这个字符串中需要出现包名分隔符.。一般这个属性会配合singleTask启动模式一起使用。任务栈可以存在多个,因而会分为前台任务栈后台任务栈。后台任务栈中的Activity都处于暂停状态。通过启动后台任务栈中的Activity,可以将后台任务栈切换到前台。

如何为Activity指定启动模式

有两种方式可以为Activity指定启动模式。一种是直接在AndroidManifest文件中为Activity指定launchMode属性。如下所示,就为Activity指定了singleTask启动模式:

<activity
        android:name=".MainActivity"
        android:launchMode="singleTask">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
</activity>

另一种是在代码中为Intent添加flags标志位指定启动模式。如下所示,就通过singleTask模式启动了Activity:

Intent intent=new Intent(MainActivity.this,ViewActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

这两种启动模式都可以很方便地为Activity指定启动模式,但是也存在部分区别。从优先级来看,第二种方式优先于第一种方式。从指定范围来看,也存在少数不同。例如,第一种方式无法直接设置FLAG_ACTIVITY_CLEAR_TOP标志位,而第二种方式则无法直接指定singleInstance启动模式。

Activity中常见的标志位

Intent.FLAG_ACTIVITY_NEW_TASK

对应singleTask启动模式。

Intent.FLAG_ACTIVITY_SINGLE_TOP

对应singleTop启动模式。

Intent.FLAG_ACTIVITY_CLEAR_TOP

这个标志位一般和singleTask配合使用,实际上singleTask默认就包含了这一标志位。它的作用是将任务栈中被启动Activity实例之上的所有Activity实例出栈。如果被启动Activity的启动模式是singleTask,则它的onNewIntent方法将被调用。需要注意的是,如果被启动Activity的启动模式是standard,则任务栈内该Activity实例及其以上的Activity都会出栈,然后Android系统会创建一个新的Activity实例加入栈内。

Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

这个标志位的作用是将Activity从最近启动的列表中移除,在特殊情况下有用,对应AndroidManifest文件中的excludeFromRecents属性。如下所示:

<activity
        android:name=".MainActivity"
        android:excludeFromRecents="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
</activity>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值