Activity的taskAffinity属性 - Android - ITeye技术网站

Activity的归属,也就是Activity应该在哪个Task中,Activity与Task的吸附关系。我们知道,一般情况下在同一个应用中,启动的Activity都在同一个Task中,它们在该Task中度过自己的生命周期,这些Activity是从一而终的好榜样。

那么为什么我们创建的Activity会进入这个Task中?它们会转到其它的Task中吗?如果转到其它的Task中,它们会到什么样的Task中去?

解决这些问题的关键,在于每个Activity的taskAffinity属性。

每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task。如果一个Activity没有显式的指明该Activity的taskAffinity,那么它的这个属性就等于Application指明的taskAffinity,如果Application也没有指明,那么该taskAffinity的值就等于包名。而Task也有自己的affinity属性,它的值等于它的根Activity的taskAffinity的值。

一开始,创建的Activity都会在创建它的Task中,并且大部分都在这里度过了它的整个生命。然而有一些情况,创建的Activity会被分配其它的Task中去,有的甚至,本来在一个Task中,之后出现了转移。我们首先分析一下android文档给我们介绍的两种情况。

第一种情况。如果该Activity的allowTaskReparenting设置为true,它进入后台,当一个和它有相同affinity的Task进入前台时,它会重新宿主,进入到该前台的task中。

我们验证一下这种情况。
Application Activity taskAffinity allowTaskReparenting
application1 Activity1 com.winuxxan.affinity true
application2 Activity2 com.winuxxan.affinity false

我们创建两个工程,application1和application2,分别含有Activity1和Activity2,它们的taskAffinity相同,Activity1的allowTaskReparenting为true。

首先,我们启动application1,加载Activity1,然后按Home键,使该task(假设为task1)进入后台。然后启动application2,默认加载Activity2。

我们看到了什么现象?没错,本来应该是显示Activity2,但是我们却看到了Activity1。实际上Activity2也被加载了,只是Activity1重新宿主,所以看到了Activity1。

第二种情况。如果加载某个Activity的intent,Flag被设置成FLAG_ACTIVITY_NEW_TASK时,它会首先检查是否存在与自己taskAffinity相同的Task,如果存在,那么它会直接宿主到该Task中,如果不存在则重新创建Task。

我们来做一个测试。

我们首先写一个应用,它有两个Activity(Activity1和Activity2),AndroidManifest.xml如下:

<application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Activity1"
                  android:taskAffinity="com.winuxxan.task"
                  android:label="@string/app_name">
        </activity>
        <activity android:name=".Activity2">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

Activity2的代码如下:

public class Activity2 extends Activity { 
        private static final String TAG = "Activity2"; 
        @Override
        protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.main2);   
        } 
              
        @Override
        public boolean onTouchEvent(MotionEvent event) { 
            Intent intent = new Intent(this, Activity1.class); 
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
            startActivity(intent); 
            return super.onTouchEvent(event); 
        } 
    }

然后,我们再写一个应用MyActivity,它包含一个Activity(MyActivity),AndroidManifest.xml如下:

<application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MyActivity"
                  android:taskAffinity="com.winuxxan.task"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

我们首先启动MyActivity,然后按Home键,返回到桌面,然后打开Activity2,点击Activity2,进入Activity1。然后按返回键。

我们发现,我们进入Activity的顺序为Activity2->Activity1,而返回时顺序为Activity1->MyActivity。这就说明了一个问题,Activity1在启动时,重新宿主到了MyActivity所在的Task中去了。

以上是验证了文档中提出的两种TaskAffinity的用法。

下面就是见证奇迹的时刻,同志们,不要眨眼!

我们现在将上一文中的launchMode和本文讲的taskAffinity结合起来。

首先是singleTask加载模式与taskAffinity的结合。

我们还是用上一文中的singleTask的代码,这里就不在列出来了,请读者自己查阅上一文。唯一不同的就是,我们为MyActivity和Activity1设置成相同的taskAffinity,重新执行上文的测试。

我们发现测试结果令我们惊讶:从同一应用程序启动singleTask和不同应用程序启动的结果完全与上文讲的相反!

我们经过思考,就可以把从同一应用程序执行和从不同应用程序执行另种方式同一起来,得到一个结论:

当一个应用程序加载一个singleTask模式的Activity时,首先该Activity会检查是否存在与它的taskAffinity相同的Task。

1、如果存在,那么检查是否实例化,如果已经实例化,那么销毁在该Activity以上的Activity并调用onNewIntent。如果没有实例化,那么该Activity实例化并入栈。

2、如果不存在,那么就重新创建Task,并入栈。

用一个流程来表示:

然后我们来检测singleInstance模式融入taskAffinity时的情况,我们也是用上文中测试singleInstance的例子,在此不列出,读者翻阅前文查阅。唯一不同的是,我们将MyActivity和Activity2设置成相同的taskAffinity。

我们发现测试结果也有一定的出入,就是,当从singleInstance中启动Activity时,并没用重新创建一个Task,而是进入了和它具有相同affinity的MyActivity所在的Task。

于是,我们也能得到以下结论:

1、当一个应用程序加载一个singleInstance模式的Activity时,如果该Activity没有被实例化,那么就重新创建一个Task,并入栈,如果已经被实例化,那么就调用该Activity的onNewIntent;

2、singleInstance的Activity所在的Task不允许存在其他Activity,任何从该Activity加载的其它Actiivty(假设为Activity2)都会被放入其它的Task中,如果存在与Activity2相同affinity的Task,则在该Task内创建Activity2。如果不存在,则重新生成新的Task并入栈。

分享到:
ScheduledExecutorService | Java Annotation注释语法
  • 2011-07-12 16:02
  • 浏览 9044
  • 评论(3)
  • 分类:移动开发
  • 相关推荐
评论
3 楼 qianhen136 2011-12-12  
受教受教

2 楼 yelinsen05 2011-08-17  
80245089 写道
你好,我有以为问题请教下

首先,我们启动application1,加载Activity1,然后按Home键,使该task(假设为task1)进入后台。然后启动application2,默认加载Activity2。

我们看到了什么现象?没错,本来应该是显示Activity2,但是我们却看到了Activity1。实际上Activity2也被加载了,只是Activity1重新宿主,所以看到了Activity1。

1.为什么会有粗体的标识的现象.还有如何判断Activity2已经被加载过.....在Activity2中的onCreate打印日志,根本没有打印出来.

你好! 首先导致这种现象的原因已经前面已经写到了---
"如果该Activity的allowTaskReparenting设置为true,它进入后台,当一个和它有相同affinity的Task进入前台时,它会重新宿主,进入到该前台的task中。"

然后如何判断activity2已经加载过呢?
在activity启动时android有默认log的!
08-17 07:29:29.421: INFO/ActivityManager(111): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=“packagename” } from pid 219
这里的packagename可以看出activity2有木有被加载过!

1 楼 80245089 2011-08-17  
你好,我有以为问题请教下

首先,我们启动application1,加载Activity1,然后按Home键,使该task(假设为task1)进入后台。然后启动application2,默认加载Activity2。

我们看到了什么现象?没错,本来应该是显示Activity2,但是我们却看到了Activity1。实际上Activity2也被加载了,只是Activity1重新宿主,所以看到了Activity1。

1.为什么会有粗体的标识的现象.还有如何判断Activity2已经被加载过.....在Activity2中的onCreate打印日志,根本没有打印出来.

转载于:https://www.cnblogs.com/seven1979/p/4342095.html

Activity的taskAffinity属性相关推荐

  1. 【Android 应用开发】Activity 任务亲和性 taskAffinity 设置 ( taskAffinity 属性 )

    文章目录 I . 任务亲和性 ( taskAffinity ) 简介 II . 任务亲和性 ( taskAffinity ) 设置 III . 任务亲和性 ( taskAffinity ) 与 FLA ...

  2. 关于taskAffinity属性的使用

    前不久修改Gallery2,发现Camera没有Manifest.xml文件,而且是和Gallery2一起进行编译的,而将两个应用关联起来的就是taskAffinity属性了 说实话,我还从来没用过这 ...

  3. android 当中taskAffinity属性与launchMode相关

    一.本文尝试解释以下问题 1.  Activity被启动之后放在哪个任务栈当中?与哪些因素有关? 2.  Activity的四种启动模式对Activity的启动有哪些影响? 3.  在Activity ...

  4. 结合源码谈谈Activity的exported属性

    Activity的exported属性在单个App可能用得比较少,但对于对外接口的Activity或公司内部多个应用间接口调用的设计会有比较大的影响.本文基于android 6.0.1的源码谈谈Act ...

  5. taskAffinity属性的奇特效果

    加载某个Activity的intent,Flag被设置成FLAG_ACTIVITY_NEW_TASK时,它会首先检查是否存在与自己taskAffinity相同的Task,如果存在,那么它会直接宿主到该 ...

  6. Activity的属性taskAffinity

    参考资料 https://blog.csdn.net/ljz2009y/article/details/26621815(静下心看,是篇不错的文章) 原文有些啰嗦,借用这篇文章中的demo,和大家一起 ...

  7. Android总结篇系列:Activity Intent Flags及Task相关属性

    同上文一样,本文主要引用自网上现有博文,并加上一些自己的理解,在此感谢原作者. 原文地址: http://blog.csdn.net/liuhe688/article/details/6761337 ...

  8. Activity的LaunchMode和taskAffinity

    Thanks to:http://www.cnblogs.com/SteveMing/archive/2012/04/24/2459575.html [原]Activity的LaunchMode和ta ...

  9. Android Activity要点(2)

    一.带返回值的Activity回退过程 一般情况下,我们要从当前Activity跳转到另一个Activity,采用的方法是通过startActivity(Intent)来携带数据并实现跳转 有时候又需 ...

最新文章

  1. 使用余弦相似度算法计算文本相似度-数学
  2. ORA-01078与LRM-00109报错解决
  3. rabbitmq实战:高效部署分布式消息队列_一文看懂消息队列中间件--AMQ及部署介绍...
  4. SQLServer DBA 三十问
  5. Nginx深入了解-基础(一)
  6. python爬取小说写入txt_对新笔趣阁小说进行爬取,保存和下载!这就是Python的魅力...
  7. 为啥地址线是20根则存储单元个数为2的20
  8. mysql 只返回第一条_mybatis 关联查询时,从表只返回第一条记录解决办法
  9. 关于Debug和Release之本质区别的讨论(转载)
  10. Laravel核心技术解析(1)—— Composer 组件管理与自动加载
  11. 关于Maven项目build时出现No compiler is provided in this environment的处理
  12. air写文件 SecurityError: fileWriteResource 时报错的解决方法
  13. 367.有效的完全平方数
  14. 掩膜裁剪tif步骤_(8)空间数据投影变换、数据裁剪、拼接及提取
  15. js如何调用本地java代码_在javascript代码中调用Java方法
  16. 《算法笔记》胡凡 例题/练习 答案
  17. 2021数据安全与个人信息保护技术白皮书
  18. 逻辑回归算法原理及用于解决多分类问题
  19. 太极图形html5代码,太极图案用html5怎样
  20. pg_repack使用

热门文章

  1. socket多线程方式案例
  2. H3 BPM报销流程开发示例
  3. C++使用Windows API CreateMutex函数多线程编程
  4. hibernate.properties与hibernate.cfg.xml 区别
  5. Android -- 自定义ProgressBar图片
  6. request,response,session,application,out对象的常用调用的函数
  7. 知识的深度跟知识的广度
  8. 【狂人小白】如何将Java项目发布到Maven中
  9. Vue.js之组件及其易错点
  10. Java格式化Date为字符串的高级写法