当前位置: 首页 > news >正文

Activity的taskAffinity属性

引用地址: http://yelinsen.iteye.com/blog/1122547

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并入栈。

转载于:https://www.cnblogs.com/zhinan/archive/2011/07/17/2108681.html

相关文章:

  • C# Winform利用POST传值方式模拟表单提交数据(Winform与网页交互)
  • Oracle Namespace 说明
  • linux目录配置 FHS
  • 排除软件缺陷的两种重要手段
  • 我收藏了 NHibernate之旅系列文章导航
  • 首篇文章测试。
  • hdu 2159 FATE 解题报告
  • Google Native Client介紹
  • 20110814炒股日记--关于内外盘【600192长城电工】
  • DELPHI 获取错误信息
  • zoj1094 Matrix Chain Multiplication(模拟)
  • 腾讯研发项目总监:互联网产品开发中的“快”字诀
  • libca.so: cannot open shared object
  • 一步一步学Silverlight 2系列(15):数据与通信之ASMX
  • 提交表单JS验证--精辟
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • EOS是什么
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • mysql 数据库四种事务隔离级别
  • Spring-boot 启动时碰到的错误
  • Wamp集成环境 添加PHP的新版本
  • windows下使用nginx调试简介
  • 观察者模式实现非直接耦合
  • 汉诺塔算法
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • # Maven错误Error executing Maven
  • # Panda3d 碰撞检测系统介绍
  • (10)STL算法之搜索(二) 二分查找
  • (黑马C++)L06 重载与继承
  • (利用IDEA+Maven)定制属于自己的jar包
  • (四)JPA - JQPL 实现增删改查
  • (推荐)叮当——中文语音对话机器人
  • (转)Google的Objective-C编码规范
  • (转载)在C#用WM_COPYDATA消息来实现两个进程之间传递数据
  • .helper勒索病毒的最新威胁:如何恢复您的数据?
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .net下的富文本编辑器FCKeditor的配置方法
  • /deep/和 >>>以及 ::v-deep 三者的区别
  • /var/log/cvslog 太大
  • [ Linux ] git工具的基本使用(仓库的构建,提交)
  • []error LNK2001: unresolved external symbol _m
  • [1159]adb判断手机屏幕状态并点亮屏幕
  • [2010-8-30]
  • [2024] 十大免费电脑数据恢复软件——轻松恢复电脑上已删除文件
  • [Android Studio] 开发Java 程序
  • [Android]使用Retrofit进行网络请求
  • [bzoj1324]Exca王者之剑_最小割
  • [Django开源学习 1]django-vue-admin
  • [LeetCode] Merge Two Sorted Lists
  • [Linux] 一文理解HTTPS协议:什么是HTTPS协议、HTTPS协议如何加密数据、什么是CA证书(数字证书)...
  • [luoguP2401] 不等数列
  • [NOIP 2003] 栈(三种方法:DP、数论、搜索)