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的包名。

结束。

时间: 2024-08-29 10:49:18

Android关于Task的一些实践之SingleTask, SingleInstance和TaskAffinity的相关文章

Android中Task任务栈的分配

首先我们来看下Task的定义,Google是这样定义Task的:a task is what the user experiences as an "application." It's a group of related activities, arranged in a stack. A task is a stack of activities, not a class or an element in the manifest file. 这意思就是说Task实际上是一个Ac

android的task任务栈

转自http://blog.csdn.net/liuhe688/article/details/6761337 古人學問無遺力,少壯工夫老始成.紙上得來終覺淺,絕知此事要躬行.南宋.陸遊<冬夜讀書示子聿(yù)> 软件行业也是一样,多少前辈不遗余力的奋斗才出现了软件行业的繁荣的景象,其中已有不少成为大师级人物.今天我们站在伟人的肩膀上,自然会有不少的优势,但不要忘了,要在对技术的认知方面有所提升,仍需我们去实践,去实践. 今天我们来讲一下Activity的task相关内容. 上次我们讲到Act

android之Task和Back Stack(回退栈)

通常一个应用程序包括多个Activity,我们在使用程序是,一个Activity到另一个Activity,又到别的Activity,然后我们按下返回键又能按打开的顺序,倒叙返回.android中是怎么做到的?Task和Back Stack与此密不可分. Task存储了一组页面的集合,并且这个集合会被排列到一个叫Back Stack中,保存的目的在于记录Activity的打开顺序. 特点:系统会给每个程序分配唯一的Task和回退栈. 回退栈的特点:先进后出. 改变Activity的排序方式:是通过

Android热补丁动态更新实践

前言 好几个月之前关于Android App热补丁修复火了一把,源于QQ空间团队的一篇文章安卓App热补丁动态修复技术介绍,然后各大厂的开源项目都出来了,本文的实践基于HotFix,也就是QQ空间技术团队那篇文章所应用的技术,笔者会把整个过程的细节和思路在文章中详说,研究这个的出发点也是为了能紧急修复app的bug,而不需要重复发包,不需要用户重新下载app就能把问题解决,个人觉得这个还是蛮有价值的,虽然老板不知道-.. 项目结构 这里笔者创建一个新的项目"HotFixDemo",带大

Android ListView复杂列表优化实践

原文:Android ListView复杂列表优化实践 很多社交App都不免会涉及到复杂的列表元素实现,一个列表上面可能大量的图片,不定长的评论列表,给手机端的程序员带来了不少的挑战.本文就是在实现复杂的列表滑动的情况下,利用已知的优化方法指导下的一次优化实践,旨在提升ListView的滑动流畅度,为用户带来良好的体验. 1:设计稿: 这是列表中可能出现的ItemView,有两种,但是又有许多相同的地方,比如一样有点赞的图片,评论等...其中,评论和点赞的数量是可变的. 2:使用一般布局带来的问

【读书笔记】《Android应用性能优化最佳实践》

<第一行代码>读书笔记 一.引言 二.读书内容 书名:<Android应用性能优化最佳实践> 作者:罗彧成 (腾讯音乐Android开发总监) 出版社:机械工业出版社 封面: 三.书籍评价 四.个人心得 五.参考文档

Google Developing for Android 二 - Memory 最佳实践 // lightSky‘Blog

Google Developing for Android 二 - Memory 最佳实践 |   分类于 Android最佳实践 原文:Developing for Android, II The Rules: Memory 在决定应用的行为,是否有好的用户体验以及整体的设备体验来说,内存的使用可能是独立因素中最重要的.内存因素包括应用的内存占用,以及内存搅动(导致的垃圾回收会对运行期间的性能有影响). 避免在循环中分配内存 内存分配虽然不可避免,但是应尽可能的避免,特别是在平凡的调用的代码块

【Android开发-4】进入实践,最喜欢折腾的计算器

前言:前面对项目文件有了感性认识,接下来我们就需要通过不断实践,对项目的文件有理性的认识.以前折腾Unity3d.IOS开发都是拿计算器开刀,所以这次Android开发实践也不例外,继续拿计算器折腾.通过本人总结,你通过折腾计算器,可以学习掌握到对文本.按钮.输入框控件的事件监听触发和一些控件读写操作,编程语言可以接触到字符串的分割.拼接.查找等方法使用,还有if-else,switch控制语句的使用:总之通过操作一款简单的计算器,可以基本熟悉该开发环境下的流程和编程语言的使用. 首先展示下折腾

Android 6.0 源代码编译实践

http://www.judymax.com/archives/1087 Android 6.0 源代码编译实践 https://mirrors.tuna.tsinghua.edu.cn/help/AOSP/ 清华大学android镜像