android:taskAffinity 
     Activity为Task拥有的一个affinity。拥有相同的affinity的Activity理论上属于相同的Task(在用户的角度是相同的“应用程序”)。Task的affinity是由它的根Activity决定的。

    affinity决定两件事情——Activity重新宿主的Task(参考allowTaskReparenting特性)和使用FLAG_ACTIVITY_NEW_TASK标志启动的Activity宿主的Task。

    默认情况,一个应用程序中的所有Activity都拥有相同的affinity。捏可以设定这个特性来重组它们,甚至可以把不同应用程序中定义的Activity放置到相同的Task中。为了明确Activity不宿主特定的Task,设定该特性为空的字符串。

    如果这个特性没有设置,Activity将从应用程序的设定那里继承下来(参考元素的taskAffinity特性)。应用程序默认的affinity的名字是元素中设定的package名。

    

     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如下:

                           android:taskAffinity="com.winuxxan.task"
                  android:label="@string/app_name">
        
        
            
               

            

        
   

    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如下:

                           android:taskAffinity="com.winuxxan.task"
                  android:label="@string/app_name">
            
               
               
            

         

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

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

 

还有以下两个结论: 
1、当一个应用程序加载一个singleTask模式的Activity时,首先该Activity会检查是否存在与它的taskAffinity相同的Task:  如果存在,那么检查是否实例化,如果已经实例化,那么销毁在该Activity以上的Activity并调用onNewIntent。如果没有实例化,那么该Activity实例化并入栈。如果不存在,那么就重新创建Task,并入栈。

2、当一个应用程序加载一个singleInstance模式的Activity时,如果该Activity没有被实例化,那么就重新创建一个Task,并入栈,如果已经被实例化,那么就调用该Activity的onNewIntent;singleInstance的Activity所在的Task不允许存在其他Activity,任何从该Activity加载的其它 Actiivty(假设为Activity2)都会被放入其它的Task中,如果存在与Activity2相同affinity的Task,则在该 Task内创建Activity2。如果不存在,则重新生成新的Task并入栈。

更多相关文章

  1. [置顶] Android之 AndroidManifest.xml 文件解析
  2. Android(安卓)的一些基本问题解决方法(android studio)
  3. MTP 看不到软件创建的文件夹(Android端)
  4. 【 Android(安卓)10 系统启动 】系列 -- Launcher(应用门户)
  5. android 模拟器手机如何添加文件到sd卡?
  6. Android应用程序四大组件之使用AIDL如何实现跨进程调用Service
  7. Android(安卓)OpenCV_face使用OpenCV3.20的一个免安装OpenCV Man
  8. Android之Handler有感(二)
  9. Android(安卓)4高级编程(第三版)创建应用程序和Activity

随机推荐

  1. React新特性一览
  2. 紫微圣人的程序员人生 [原创IT小说]--第
  3. JavaScript中的基本字符串与字符串对象的
  4. JavaScript中是如何定义私有变量的
  5. 浅谈时间复杂度
  6. 什么是Linux系统?哪个发行版本好?
  7. 记录一次体体现前端工具仔综合实力的实际
  8. 今天聊点干货—关于CSS样式来源
  9. Severlet跳转JSP,切换div
  10. 关于this,你真的了解吗?