zoukankan      html  css  js  c++  java
  • Activity的taskAffinity属性

    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并入栈。
    分享到:
    评论
    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打印日志,根本没有打印出来.
  • 相关阅读:
    1104 Sum of Number Segments (20 分)(数学问题)
    1092 To Buy or Not to Buy (20 分)(hash散列)
    1082 Read Number in Chinese (25 分)(字符串处理)【背】
    1105 Spiral Matrix (25 分)(模拟)
    初识网络安全及搭建网站(内网)
    HTML5开发者需要了解的技巧和工具汇总(转)
    native+web开发模式之web前端经验分享
    移动平台3G手机网站前端开发布局技巧汇总(转)
    Asp.net 中图片存储数据库以及页面读取显示通用方法详解附源码下载
    使用H3Viewer来查看VS2010的帮助文档
  • 原文地址:https://www.cnblogs.com/seven1979/p/4342095.html
Copyright © 2011-2022 走看看