Activity 四种启动模式的区别

Android Activity 四种启动模式的区别
分享到:

通过昨天的学习,相信大家已经对Android Activity的四种启动模式有了非常清楚的认识,那么,Android Activity 这四种启动模式有什么区别呢?这就是今天本文要给大家讲解的内容!

1、standard标准模式

在standard模式也就是默认模式下,不需要配置launchMode。此时的AndroidManifest.xml如代码清单1-1所示。

代码清单1-1 AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="feixun.com.jiang"
        android:versionCode="1"
        android:versionName="1.0">
      <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Fx_Main"
                android:label="@string/app_name" >
            <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
          </activity>
        <activity android:name=".Activity2" android:label="@string/Ac2"/>
        <activity android:name=".Activity3" android:label="@string/Ac3/>

      </application>
      <uses-sdk android:minSdkVersion="4" />

    </manifest>

运行例子,从Fx_Main开始,一直点回到Activity2按钮时,Log信息如图1所示。

Activity 四种启动模式的区别_第1张图片
图1 Standard启动模式下Log信息

发现每次都创建了Activity2的新实例。standard的加载模式就是这样的,Intent将发送给它新的Activity实例。

现在点击Android设备的回退键,可以看到Log信息按照刚才创建Activity实例的倒序依次出现,类似退栈的操作,而刚才操作跳转按钮的过程是压栈的操作。

2、 singleTop

singleTop和standard模式,都会将Intent发送到新的实例(如果已经有了,singleTask模式和singleInstance模式不发送到新的实例)。不过,singleTop要求如果创建intent时栈顶已经有要创建Activity的实例,则将Intent发送给该实例,而不发送给新的实例。

还是用刚才的示例,只需将Activity2的launchMode改为singleTop,就能看到区别。修改后AndroidManifest.xml中代码如代码清单1-2所示。

代码清单1-2 AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="feixun.com.jiang"
        android:versionCode="1"
        android:versionName="1.0">
      <application android:icon="@drawable/icon" android:label="@string/app_name">
          <activity android:name=".Fx_Main"
                android:label="@string/app_name" >
            <intent-filter>
               <action android:name="android.intent.action.MAIN" />
               <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
          </activity>
         <activity android:name=".Activity2" android:label="@string/Ac2" 
               android:launchMode="singleTop"/ >
         <activity android:name=".Activity3" android:label="@string/Ac3/>

       </application>
       <uses-sdk android:minSdkVersion="4" />

     </manifest>

运行Fx_Main,跳转到Activity2---->Actvity2时会发现,单击多少遍按钮,都是相同的Activity2实例,因为该实例在栈顶,所以不会创建新的实例。如果回退,回到Fx_Main,将退出应用,如图2所示。


图2 singleTop模式下“跳转到AC2”的Log信息

singleTop模式,可用来解决栈顶多个重复相同的Activity的问题。

如果是Fx_Main跳转到Activity2,再跳转到Fx_Main,行为就和standard一样了,会在Activity2跳转到Fx_Main时创建Fx_Main的新实例,因为当时的栈顶不是Activity2实例,如图3所示。


图3 singleTop模式下“跳转到AC2”后“跳回到Main”的Log信息

3、singleTask

singleTask模式和后面的singleInstance模式都是只创建一个实例的。

当Intent到来,需要创建singleTask模式Activity时,系统会检查栈里面是否已经有该Activity的实例。如果有直接将Intent发送给它(注意此时原在此Activity栈中上面的Activity将会被关闭)。

把Activity2的启动模式改成singleTask,修改后AndroidManifest.xml中代码如代码清单1-3所示。

代码清单1-3 AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="feixun.com.jiang"
    android:versionCode="1"
    android:versionName="1.0">
      <application android:icon="@drawable/icon" android:label="@string/app_name">
          <activity android:name=".Fx_Main"
                android:label="@string/app_name" >
            <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
          </activity>
        <activity android:name=".Activity2" android:label="@string/Ac2" 
                android:launchMode="singleTask"/ >
        <activity android:name=".Activity3" android:label="@string/Ac3/>

      </application>
      <uses-sdk android:minSdkVersion="4" />

    </manifest> 

启动Fx_Main,跳转到Activity2---->Activity3---->Actvity2,此时看Log信息,如图4所示。


图4 singleTask启动模式下Log信息

可见从AC3再跳转到AC2时,因为AC2之前在栈中是存在的所以不生成新的AC2实例,而是在栈中找到此AC2,并将在AC2上面的AC3关闭,所以此时栈中只有Fx_Main和AC2,在AC2点返回会直接退到Fx_Main然后退出。

4、singleInstance

在singleInstance模式下,加载该Activity时如果没有实例化,它会在创建新的Task后,实例化入栈,如果已经存在,则直接调用onNewIntent,该Activity的Task中不允许启动其他的Activity,任何从该Activity启动的其他Activity都将被放到其他Task中,先检查是否有在应用的Task,没有的话就创建。

在这里介绍一下Task(任务)的概念。按照字面意思,任务就是自己要实现的一个目的,而在Android中的Task的定义是一系列Activity的集合,即要达到自己最终要到的Actvity,之前所有经历过的Actvity的集合。它可以是同一个应用内部的,也可以是两个不同应用的。Task可以认为是一个栈,可放入多个Activity。比如,启动一个应用,那么 Android就创建了一个Task,然后启动这个应用的入口Activity,就是intent-filter中配置为main和launch的那个。这个Activity是根(Root)Activity,可能会在它的界面调用其他Activity,这些Activity如果按照上面那3个模式,也会在这个栈(Task)中,只是实例化的策略不同而已。

把Activity2的启动模式改成singleInstance,修改后AndroidManifest.xml中代码如代码清单1-4所示。

代码清单1-4 AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="feixun.com.jiang"
    android:versionCode="1"
    android:versionName="1.0">
      <application android:icon="@drawable/icon" android:label="@string/app_name">
          <activity android:name=".Fx_Main"
                android:label="@string/app_name" >
            <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
          </activity>
        <activity android:name=".Activity2" android:label="@string/Ac2" 
                android:launchMode="singleInstance"/ >
        <activity android:name=".Activity3" android:label="@string/Ac3/>

      </application>
      <uses-sdk android:minSdkVersion="4" />

    </manifest>

然后进行测试,启动Fx_Main---->Actvity2---->Actvity3然后看一下Log信息,如图5所示。


图5 singleInstance启动模式下Log信息

可以看到Fx_Main以及Activity3的Task ID为9,而Actvity2的Task ID为10,此时在Actvity3单击“返回”按钮会发现先退到Fx_Main,继续返回会回到Actvity2最后退出。从该过程可以看出:如果从其他应用程序调用singleInstance模式的Activity(Fx_Main),从该Activity开启其他Activity(Activity2)时,会创建一个新的Task(Task ID为10的那个),实际上,如果包含该Activity(Activity2)的Task已经运行的话,他会在该运行的Task中重新创建。

经过上述的介绍,用下面的表格来进行一个简单的总结,如表1-1所示。

表1-1 Activity4种启动模式对比

区别 是否允许多个实例 如何决定所属Task 是否每次都生成新实例 是否允许其他Activity存在于本Task内
standard 可被多次实例化,同一个Task的不同的实例可位于不同的Task中,每个Task也可包含多个实例 存放于Start Activity()的
Task。除非设置
FLAG_ACTIVITY
_NEW_TASK标记
允许
singleTop 同standard 同standard 如果寄存Activity的栈顶为该Activity,则直接用该Activity处理;否则,创建新实例 允许
singleTask 不能有多个实例。由于该模式下Activity总是位于栈顶,所以Actvity在同一个设备里最多只有一个实例 放入新的Task内,并且位于该Task的根 只有在第一次才创建新的实例,其他情况复用该Activity 允许。如果存放singleTask的栈寄存在Task内,响应一个Intent时,如果singleTask位于栈顶,则处理Intent,否则会丢失Intent,但该Task会处于前台
singleInstance 同singleTask 同singleTask 同singleTask 不允许

你可能感兴趣的:(Activity 四种启动模式的区别)