• Android关于Task的一些实践之SingleTask, SingleInstance和TaskAffinity


    上一篇文章粗略地介绍了一下关于Android中Task的基本知识。只是实践才是检验真理的唯一标准,所以。今天就来试验一下Task中的launchMode是否真的实现了文档所说的那样。

    首先。定义三个Activity。MainActivity打开SecondActivity,SecondActivity打开ThirdActivity,例如以下所看到的:

     


    以下。我们定义Second Activity的Launch Mode。分别有以下几种情况:

    1)Standard(即不定义)

    首先是默认情况下。什么都不定义。例如以下:

        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.lms.taskdemo.MainActivity"
                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="com.lms.taskdemo.SecondActivity">
            </activity>
            <activity android:name="com.lms.taskdemo.ThirdActivity" >
            </activity>
        </application>
    顺序打开三个Activity,看看结果:

    04-21 15:23:28.373: V/com.lms.taskdemo(20473): Task : 70
    04-21 15:23:28.373: V/com.lms.taskdemo(20473): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-21 15:23:28.373: V/com.lms.taskdemo(20473): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-21 15:23:28.373: V/com.lms.taskdemo(20473): Number of activities : 1
    04-21 15:23:28.373: V/com.lms.taskdemo(20473): Number of running activities: 1
    04-21 15:23:31.336: V/com.lms.taskdemo(20473): Task : 70
    04-21 15:23:31.336: V/com.lms.taskdemo(20473): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-21 15:23:31.336: V/com.lms.taskdemo(20473): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity}
    04-21 15:23:31.336: V/com.lms.taskdemo(20473): Number of activities : 2
    04-21 15:23:31.336: V/com.lms.taskdemo(20473): Number of running activities: 2
    04-21 15:23:33.999: V/com.lms.taskdemo(20473): Task : 70
    04-21 15:23:33.999: V/com.lms.taskdemo(20473): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-21 15:23:33.999: V/com.lms.taskdemo(20473): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.ThirdActivity}
    04-21 15:23:33.999: V/com.lms.taskdemo(20473): Number of activities : 3
    04-21 15:23:33.999: V/com.lms.taskdemo(20473): Number of running activities: 3

    能够看到三个Activity,都是在同个Task中的。

    2)SingleTask

    为Second Activity,定义其launch mode 为 “singleTask”。例如以下:

        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.lms.taskdemo.MainActivity"
                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="com.lms.taskdemo.SecondActivity"
                android:launchMode="singleTask">
            </activity>
            <activity android:name="com.lms.taskdemo.ThirdActivity" >
            </activity>
        </application>

    再来看看其结果,例如以下:

    04-22 10:31:26.197: V/com.lms.taskdemo(924): Task : 162
    04-22 10:31:26.217: V/com.lms.taskdemo(924): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-22 10:31:26.217: V/com.lms.taskdemo(924): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-22 10:31:26.217: V/com.lms.taskdemo(924): Number of activities : 1
    04-22 10:31:26.217: V/com.lms.taskdemo(924): Number of running activities: 1
    04-22 10:31:31.112: V/com.lms.taskdemo(924): Task : 162
    04-22 10:31:31.112: V/com.lms.taskdemo(924): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-22 10:31:31.112: V/com.lms.taskdemo(924): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity}
    04-22 10:31:31.112: V/com.lms.taskdemo(924): Number of activities : 2
    04-22 10:31:31.112: V/com.lms.taskdemo(924): Number of running activities: 2
    04-22 10:31:32.884: V/com.lms.taskdemo(924): Task : 162
    04-22 10:31:32.884: V/com.lms.taskdemo(924): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-22 10:31:32.884: V/com.lms.taskdemo(924): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.ThirdActivity}
    04-22 10:31:32.884: V/com.lms.taskdemo(924): Number of activities : 3
    04-22 10:31:32.884: V/com.lms.taskdemo(924): Number of running activities: 2

    发现尽管定义了SingleTask,但Second Activity和Main Activity还是在同一个Task中。这跟我们期望的不符。原因事实上在于,设置了launchMode = SingleTask启动的Activity,在启动的时候,会去查找跟它的taskAffinity同样的task,假设存在这样一个task,就在这个task中启动,假设不存在这样一个task,才创建一个新的task,并在新task中启动。

    而在这里,由于没有为各个activity定义taskAffinity,那么默认的affinity值就是包名,那么几个Activity都是一样的,所以就在相同的Task中启动了。

    3)Single Task Different Task Affinity

    以下。我们分别为Main Activity和 Second Activity设置不同的TaskAffinity值,例如以下:

        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.lms.taskdemo.MainActivity"
                android:label="@string/app_name"
                android:taskAffinity="com.lms.taskdemo.MainActivity" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity
                android:name="com.lms.taskdemo.SecondActivity"
                android:launchMode="singleTask"
                android:taskAffinity="com.lms.taskdemo.SecondActivity" >
            </activity>
            <activity android:name="com.lms.taskdemo.ThirdActivity" >
            </activity>
        </application>

    以下是结果,启动的顺序是Main Activity->Second Activity->Main Activity -> Second Activity -> Third Activity

    04-22 10:26:27.818: V/com.lms.taskdemo(32677): Task : 151
    04-22 10:26:27.818: V/com.lms.taskdemo(32677): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-22 10:26:27.818: V/com.lms.taskdemo(32677): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-22 10:26:27.818: V/com.lms.taskdemo(32677): Number of activities : 1
    04-22 10:26:27.818: V/com.lms.taskdemo(32677): Number of running activities: 1
    04-22 10:26:31.362: V/com.lms.taskdemo(32677): Task : 152
    04-22 10:26:31.362: V/com.lms.taskdemo(32677): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity}
    04-22 10:26:31.362: V/com.lms.taskdemo(32677): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity}
    04-22 10:26:31.372: V/com.lms.taskdemo(32677): Number of activities : 1
    04-22 10:26:31.372: V/com.lms.taskdemo(32677): Number of running activities: 1
    04-22 10:26:36.558: V/com.lms.taskdemo(32677): Task : 151
    04-22 10:26:36.558: V/com.lms.taskdemo(32677): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-22 10:26:36.558: V/com.lms.taskdemo(32677): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-22 10:26:36.558: V/com.lms.taskdemo(32677): Number of activities : 1
    04-22 10:26:36.558: V/com.lms.taskdemo(32677): Number of running activities: 1
    04-22 10:26:39.401: V/com.lms.taskdemo(32677): Task : 153
    04-22 10:26:39.401: V/com.lms.taskdemo(32677): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity}
    04-22 10:26:39.401: V/com.lms.taskdemo(32677): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity}
    04-22 10:26:39.401: V/com.lms.taskdemo(32677): Number of activities : 1
    04-22 10:26:39.401: V/com.lms.taskdemo(32677): Number of running activities: 1
    04-22 10:26:41.123: V/com.lms.taskdemo(32677): Task : 153
    04-22 10:26:41.123: V/com.lms.taskdemo(32677): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity}
    04-22 10:26:41.123: V/com.lms.taskdemo(32677): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.ThirdActivity}
    04-22 10:26:41.123: V/com.lms.taskdemo(32677): Number of activities : 2
    04-22 10:26:41.123: V/com.lms.taskdemo(32677): Number of running activities: 2

    在上面的结果中,能够看到在启动Second Activity的时候,的确是在一个新的Task中启动了。Second Activity是这个Task中的根Activity。而由Second Activity启动的Third Activity也是在这个Task中启动的。

    4)Single Instance

    以下,我们再来看看Single Instance,相同的,先不定义Task Affinity。在AndroidManifest文件里定义例如以下:
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.lms.taskdemo.MainActivity"
                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="com.lms.taskdemo.SecondActivity"
                android:launchMode="singleInstance">
            </activity>
            <activity android:name="com.lms.taskdemo.ThirdActivity" >
            </activity>
        </application>

    以下是结果:
    04-22 10:29:43.207: V/com.lms.taskdemo(682): Task : 159
    04-22 10:29:43.207: V/com.lms.taskdemo(682): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-22 10:29:43.207: V/com.lms.taskdemo(682): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-22 10:29:43.207: V/com.lms.taskdemo(682): Number of activities : 1
    04-22 10:29:43.207: V/com.lms.taskdemo(682): Number of running activities: 1
    04-22 10:29:46.580: V/com.lms.taskdemo(682): Task : 160
    04-22 10:29:46.580: V/com.lms.taskdemo(682): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity}
    04-22 10:29:46.580: V/com.lms.taskdemo(682): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity}
    04-22 10:29:46.580: V/com.lms.taskdemo(682): Number of activities : 1
    04-22 10:29:46.580: V/com.lms.taskdemo(682): Number of running activities: 1
    04-22 10:29:48.202: V/com.lms.taskdemo(682): Task : 159
    04-22 10:29:48.202: V/com.lms.taskdemo(682): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-22 10:29:48.202: V/com.lms.taskdemo(682): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.ThirdActivity}
    04-22 10:29:48.202: V/com.lms.taskdemo(682): Number of activities : 2
    04-22 10:29:48.202: V/com.lms.taskdemo(682): Number of running activities: 1
    04-22 10:29:57.112: V/com.lms.taskdemo(682): Task : 160
    04-22 10:29:57.112: V/com.lms.taskdemo(682): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity}
    04-22 10:29:57.112: V/com.lms.taskdemo(682): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity}
    04-22 10:29:57.112: V/com.lms.taskdemo(682): Number of activities : 1
    04-22 10:29:57.112: V/com.lms.taskdemo(682): Number of running activities: 1
    能够看到启动Second Activity的时候,是在新的Task中,而当启动Third Activity的时候,它又跑回原来的Task中去了。这是跟文档描写叙述中符合的。的确是新建的Task中仅仅能有且仅有一个Activity。

    而因为我们未定义Task Affinity,所以当启动Third Activity的时候。它就会去找同样Affinity的task,所以就会找到原来的Task。也即是说,假设定义了TaskAffinity的话,那以Third Activity就应该在新的Task中创建了,以下就来验证一下。


    5)Single Instance Different Affinity

    在配置文件里定义例如以下:
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.lms.taskdemo.MainActivity"
                android:label="@string/app_name"
                android:taskAffinity="com.lms.taskdemo.MainActivity" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity
                android:name="com.lms.taskdemo.SecondActivity"
                android:launchMode="singleInstance"
                android:taskAffinity="com.lms.taskdemo.SecondActivity" >
            </activity>
            <activity android:name="com.lms.taskdemo.ThirdActivity" >
            </activity>
        </application>

    以下来看看结果,例如以下:
    04-22 10:27:58.866: V/com.lms.taskdemo(391): Task : 155
    04-22 10:27:58.866: V/com.lms.taskdemo(391): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-22 10:27:58.866: V/com.lms.taskdemo(391): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.MainActivity}
    04-22 10:27:58.866: V/com.lms.taskdemo(391): Number of activities : 1
    04-22 10:27:58.866: V/com.lms.taskdemo(391): Number of running activities: 1
    04-22 10:28:00.677: V/com.lms.taskdemo(391): Task : 156
    04-22 10:28:00.677: V/com.lms.taskdemo(391): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity}
    04-22 10:28:00.677: V/com.lms.taskdemo(391): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.SecondActivity}
    04-22 10:28:00.677: V/com.lms.taskdemo(391): Number of activities : 1
    04-22 10:28:00.677: V/com.lms.taskdemo(391): Number of running activities: 1
    04-22 10:28:02.309: V/com.lms.taskdemo(391): Task : 157
    04-22 10:28:02.309: V/com.lms.taskdemo(391): Base activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.ThirdActivity}
    04-22 10:28:02.309: V/com.lms.taskdemo(391): Current activity : ComponentInfo{com.lms.taskdemo/com.lms.taskdemo.ThirdActivity}
    04-22 10:28:02.309: V/com.lms.taskdemo(391): Number of activities : 1
    04-22 10:28:02.309: V/com.lms.taskdemo(391): Number of running activities: 1

    果然。如我们期望的那样,都是在一个新的Task中启动当前的Activity的。


    总结:

    当使用Launch Mode 来改变系统默认的任务调度的时候。假设是用到Single Task或者Single Instance的时候,还要注意到Affinity的使用,要跟Affinity配合使用。可能才干达到我们期望中的效果。而Affinity,事实上是Android提供的一个表从属意义的參数,类似于一个Tag值,它表明当前Activity属于哪一个Tag,相当的Affinity值的Activity。假设不使用其它的标志,如Single Instance之类,那么都会在存在于同一个task中。普通情况下,我们并不定义Task Affinity值。则其默认的值就是当前App的包名。

    结束。

  • 相关阅读:
    SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
    Spring各jar包的作用
    spring常见问题
    Spring+SpringMVC+MyBatis详细整合教程
    maven项目常见问题
    创建maven工程时总是带有后缀名Maven Webapp解决办法
    LOL 控制技能的解释
    java系列-安装MySql(三)
    java系列-使用maven创建web项目(二)
    Window环境下搭建MyEclipse+Tomcat+MAVEN+SVN
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/6898955.html
Copyright © 2020-2023  润新知