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.test.affinity true application2 Activity2 com.test.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.test.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.test.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并入栈。
相关推荐
为了管理Activity的生命周期和用户界面的流程,Android系统提供了一系列的机制和属性,其中包括四种不同的Activity启动模式以及taskAffinity属性。这些启动模式和属性共同作用于Activity所属的任务栈(Task)和后退...
### Android Activity 属性详解 在Android开发中,`Activity`是四大组件之一,负责处理用户交互,管理用户界面。为了使`Activity`更好地适应不同场景和需求,Android提供了丰富的属性来定制其行为。以下是对部分...
此外,通过设置 `android:taskAffinity` 属性,可以指定该 Activity 所属的任务栈,从而控制 Activity 在不同任务栈中的行为。 ##### 4. SingleInstance 模式 - **描述**:当 Activity 的启动模式设置为 `...
3. **android:clearTaskOnLaunch**:当用户再次启动一个任务时,如果设置了此属性为`true`,该任务中的所有Activity都将被清除,只显示最初启动的Activity。 4. **android:configChanges**:指定哪些配置变化会导致...
4. Manifest文件中的Activity属性: - `android:allowTaskReparenting`:允许Activity在运行时改变其所属的Task。例如,当用户从主屏幕小部件启动Activity时,可能会希望Activity与主应用的Task关联。 - `android:...
本文将详细介绍Android XML中常用的属性及其功能。 #### 二、Android Activity 属性 **1. `android:allowTaskReparenting`** - **功能描述**:此属性决定了Activity是否可以从一个任务转移到另一个任务中。 - *...
在Android应用开发中,Activity是用户界面的基本组件,它负责与用户进行交互。当我们谈论"Android模拟Activity进出栈"时,我们实际上是在讨论Activity的生命周期和任务管理,这是Android应用设计的重要部分。在这个...
此外,利用taskAffinity和allowTaskReparenting属性,可以改变Activity所属的任务栈,实现更灵活的任务管理。 Activity之间的跳转是通过Intent来实现的。Intent是一个动作的抽象描述,它携带了启动Activity所需的...
本文将深入探讨一系列关键的Android XML属性,这些属性对于理解和控制Activity的行为至关重要。 #### 1. `android:allowTaskReparenting` 此属性决定Activity是否可以从一个任务(task)移动到另一个任务。例如,...
如果Activity没有显式指定taskAffinity属性,则它将继承其所属Application的taskAffinity值;如果Application也没有指定,则taskAffinity的值就是应用的包名。 Task(intent)是指启动Task中rootActivity的Intent。...
在Android应用开发中,`Activity`作为四大组件之一,承载着界面交互的主要职责。正确地配置`Activity`的各种属性对于优化用户体验、提升应用性能至关重要。本文将详细解读`Activity`的常见属性及其作用,帮助开发者...
从给定的文件信息来看,虽然标题和描述指向了`EditText`与`TextView`的属性大全,但在部分内容中,却详细列举了与Android Activity相关的属性。因此,我将基于这部分内容,深入解析与Activity相关的各个属性,以满足...
此外,`taskAffinity`属性可以用来控制Activity所属的任务栈,通常与单例模式配合使用。 通过adb命令,开发者可以查看当前设备上各个任务栈的运行状态,从而更好地理解和调试Activity的启动模式。例如,使用`adb ...
6. **使用TaskAffinity**: 通过设置Activity的android:taskAffinity属性,可以将不同的Activity放入不同的任务栈。这样,一个栈中的Activity可以独立于其他栈,方便控制退出。 7. **使用Back Stack**: Android的...
通过设置`android:taskAffinity`属性,可以控制Activity属于哪个任务(Task)。通过合理配置,可以实现跨Task的跳转,当某个Task中所有Activity都被finish()后,整个Task也会被销毁,从而达到退出应用的效果。 四、...
### Android Activity 属性详解 在Android开发中,`Activity`是四大组件之一,它负责管理应用程序的用户界面。每一个`Activity`都代表了一个可以与用户交互的屏幕。为了更好地管理和控制`Activity`的行为,Android...
在application分支中,我们需要了解一些常见的属性,这里可以看到一些我们实用的选项,比如允许调试android:debuggable、任务关系android:taskAffinity、创建一个新的任务实用标记FLAG_ACTIVITY_NEW_TASK、为程序...
application分支中包含了Android程序的四种对象:Activity、Service、Content Provider以及Receiver。application分支的属性包括: * android:debuggable:是否允许调试 * android:taskAffinity:任务关系 * ...
7. **Task和Activity Stack**:Task是Activity的集合,理解TaskAffinity和TaskDescription,以及如何通过FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLEAR_TOP等标志调整Activity在Task中的行为,对于实现复杂的导航...