`

Activity的taskAffinity属性

 
阅读更多

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中,如果存在与A

分享到:
评论

相关推荐

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

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

    Android activity属性

    ### Android Activity 属性详解 在Android开发中,`Activity`是四大组件之一,负责处理用户交互,管理用户界面。为了使`Activity`更好地适应不同场景和需求,Android提供了丰富的属性来定制其行为。以下是对部分...

    ActivityManagerService相关流程分析

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

    Android开发中Activity属性设置小结

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

    Android模拟Activity进出栈.zip

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

    activity的设置大全

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

    EditText与TextView 属性大全

    从给定的文件信息来看,虽然标题和描述指向了`EditText`与`TextView`的属性大全,但在部分内容中,却详细列举了与Android Activity相关的属性。因此,我将基于这部分内容,深入解析与Activity相关的各个属性,以满足...

    分析如何安全退出多个Activity 多种方式

    通过设置`android:taskAffinity`属性,可以控制Activity属于哪个任务(Task)。通过合理配置,可以实现跨Task的跳转,当某个Task中所有Activity都被finish()后,整个Task也会被销毁,从而达到退出应用的效果。 四、...

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

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

    android activity和task

    4. Manifest文件中的Activity属性: - `android:allowTaskReparenting`:允许Activity在运行时改变其所属的Task。例如,当用户从主屏幕小部件启动Activity时,可能会希望Activity与主应用的Task关联。 - `android:...

    Android_XML属性大全

    - **功能描述**:此属性决定了Activity是否可以从一个任务转移到另一个任务中。 - **应用场景**:例如,一个短信应用的Activity可以在用户打开浏览器时将其转移到浏览器任务中。 **2. `android:...

    android xml属性总结

    本文将深入探讨一系列关键的Android XML属性,这些属性对于理解和控制Activity的行为至关重要。 #### 1. `android:allowTaskReparenting` 此属性决定Activity是否可以从一个任务(task)移动到另一个任务。例如,...

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

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

    androidactivity 学习

    此外,利用taskAffinity和allowTaskReparenting属性,可以改变Activity所属的任务栈,实现更灵活的任务管理。 Activity之间的跳转是通过Intent来实现的。Intent是一个动作的抽象描述,它携带了启动Activity所需的...

    Android应用源码之9.Activity高级学习.zip

    7. **Task和Activity Stack**:Task是Activity的集合,理解TaskAffinity和TaskDescription,以及如何通过FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLEAR_TOP等标志调整Activity在Task中的行为,对于实现复杂的导航...

    android 属性

    ### Android Activity 属性详解 在Android开发中,`Activity`是四大组件之一,它负责管理应用程序的用户界面。每一个`Activity`都代表了一个可以与用户交互的屏幕。为了更好地管理和控制`Activity`的行为,Android...

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

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

    Android从初级到高级代码九

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

    AndroidManifest.xml文件剖析.pdf

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

Global site tag (gtag.js) - Google Analytics