`
kobe学java
  • 浏览: 258298 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

taskAffinity属性

 
阅读更多
taskAffinity属性
分类: Android 2011-07-12 16:46 1444人阅读 评论(7) 收藏 举报
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并入栈。
分享到:
评论

相关推荐

    Android中Activity四种启动模式和taskAffinity属性详解-Rong

    为了管理Activity的生命周期和用户界面的流程,Android系统提供了一系列的机制和属性,其中包括四种不同的Activity启动模式以及taskAffinity属性。这些启动模式和属性共同作用于Activity所属的任务栈(Task)和后退...

    ActivityManagerService相关流程分析

    如果Activity没有显式指定taskAffinity属性,则它将继承其所属Application的taskAffinity值;如果Application也没有指定,则taskAffinity的值就是应用的包名。 Task(intent)是指启动Task中rootActivity的Intent。...

    android启动优化的操作,通过启动器task来进行启动优化

    1. **调整TaskAffinity**:设置正确的TaskAffinity属性,避免不必要的Task切换,减少系统资源的消耗。 2. **启动模式优化**:合理使用SingleTask、SingleInstance等启动模式,控制Activity在Task中的位置,避免重复...

    Android高级应用源码-从注册流程 分析如何安全退出多个Activity 多种方式.zip

    6. **使用TaskAffinity**: 通过设置Activity的android:taskAffinity属性,可以将不同的Activity放入不同的任务栈。这样,一个栈中的Activity可以独立于其他栈,方便控制退出。 7. **使用Back Stack**: Android的...

    Android从初级到高级代码九

    11. **Task和Back Stack**:理解任务和返回栈的概念,如何通过FLAG_ACTIVITY_*系列标记影响Activity的启动行为,以及如何通过TaskAffinity属性设置Activity的任务归属。 以上只是对Activity基础知识点的概览,实际...

    Android Activity的4种启动模式图文介绍

    TaskAffinity属性用于指定Activity所需的任务栈。 4. **singleInstance模式** singleInstance模式也是栈内复用,但它更进一步,Activity不仅会在单独的任务栈中存在,而且这个任务栈只包含这一个Activity。任何...

    EditText与TextView 属性大全

    `android:taskAffinity` 用于定义Activity与任务的关联性,通常用于控制多个Activity是否倾向于聚集在同一任务栈中。 #### 20. `android:theme` 用于指定Activity的主题,如果没有设置,将继承自应用程序的整体...

    Android activity属性

    #### android:taskAffinity 定义了`Activity`的所属任务,通常同一应用的`Activity`具有相同亲缘关系,但可以通过此属性调整。 #### android:theme 设置了`Activity`的主题,决定了UI的外观风格。若未设置,则继承...

    Android_XML属性大全

    `android:taskAffinity`** - **功能描述**:定义Activity的任务亲缘性。 - **应用场景**:如果设置为空字符串,则所有同一应用中的Activity共享相同的任务亲缘性。 **20. `android:theme`** - **功能描述**:...

    android xml属性总结

    `android:taskAffinity` 影响Activity在任务管理中的关联程度,通常用于保持同一应用内Activity的紧密联系。 #### 19. `android:theme` 定义Activity的主题样式,可以独立于整个应用的主题,实现更个性化的设计...

    activity的设置大全

    ### Activity属性设置详解 在Android应用开发中,`Activity`作为四大组件之一,承载着界面交互的主要职责。正确地配置`Activity`的各种属性对于优化用户体验、提升应用性能至关重要。本文将详细解读`Activity`的...

    Android开发中Activity属性设置小结

    17. **android:taskAffinity**:定义Activity所属的任务家族,默认情况下,同应用内的Activity具有相同的亲和性。 18. **android:theme**:指定Activity使用的主题,可以自定义或继承系统提供的主题。 19. **...

    android 属性

    `android:taskAffinity` - **描述**:控制`Activity`与任务之间的关联。 - **取值**:字符串。 - **作用**:定义`Activity`与特定任务的关联性,使得`Activity`可以被放置到特定的任务栈中。 #### 20. `android:...

    android Manifest.xml详解

    - `taskAffinity` 属性用于指定 Activity 与哪个任务关联。若不指定,默认情况下,所有 Activity 都属于同一个任务。 ##### 2. android:alwaysRetainTaskState **语法示例:** ```xml ``` **功能说明:** 该属性...

    AndroidManifest.xml文件剖析.pdf

    Activity节点的属性有很多,常用的属性包括: * android:name:Activity的名称 * android:label:Activity的标签 * android:allowTaskReparenting:是否允许任务重复 * android:alwaysRetainTaskState:是否总是...

    AndroidManifest.xml文件剖析[参考].pdf

    在application分支中,我们需要了解一些常见的属性,这里可以看到一些我们实用的选项,比如允许调试android:debuggable、任务关系android:taskAffinity、创建一个新的任务实用标记FLAG_ACTIVITY_NEW_TASK、为程序...

    ANDROID 应用完全退出

    可以通过设置Activity的`android:taskAffinity`属性,使它们属于不同的任务栈,这样finishAllActivities()或finishTask()就能更有效地清除整个任务栈,实现应用的完全退出。 5. **自定义退出方法**:在主Activity中...

    Android模拟Activity进出栈.zip

    4. **模拟Activity进出栈**:开发者可能需要在测试或特定场景下模拟Activity的进出栈行为,这通常通过Intent的FLAG属性实现,如FLAG_ACTIVITY_NEW_TASK、FLAG_ACTIVITY_CLEAR_TOP等。例如,使用FLAG_ACTIVITY_NEW_...

    Android Activity 的四种启动模式 lunchMode 和 Intent.setFlags()

    此外,通过设置 `android:taskAffinity` 属性,可以指定该 Activity 所属的任务栈,从而控制 Activity 在不同任务栈中的行为。 ##### 4. SingleInstance 模式 - **描述**:当 Activity 的启动模式设置为 `...

Global site tag (gtag.js) - Google Analytics