一、本文尝试解释以下问题

1.  Activity被启动之后放在哪个任务栈当中?与哪些因素有关?

2.  Activity的四种启动模式对Activity的启动有哪些影响?

3.  在Activity中使用startActivityForResult(intent, REQUESTCODE);和onActivityResult()

是否与被启动的Activity的launchMode有关?如果有关,有什么关系?

二、Activity被启动之后放在哪个任务栈当中?与哪些因素有关?

1.基本论断:Activity启动之后对应的任务站与Activity的两个属性taskAffinity和allowTask-

Reparenting有关

2.原理

(1)任务栈的标识----任务栈名称的确定

任务栈的标识是由任务栈的名称来确定的,例如,在通常情况下用包名标识一个唯一任务栈,清单文件如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.musictest01"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="8"android:targetSdkVersion="17" /><applicationandroid:allowBackup="true"android:theme="@style/AppTheme" ><activityandroid:name="com.example.musictest01.MainActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><activity android:name=".AActivity"></activity><activity android:name=".BActivity"></activity></application>
</manifest>

该文件当中<appliacation>和<activity>标签都没有设置taskAffinity属性,所以这个应用的默认任务栈名称就是包名"com.example.musictest01" , activity默认也会放入这个任务栈当中。

<application>当中的属性android:taskAffinity指定该应用程序默认的任务栈名称,用来标识一个唯一的任务栈,如果不设置,则默认为包名

<activity>当中的属性android:taskAffinity指定该activity的“宿主”任务栈名称

(2)情景分析:

第一步、定义宿主工程,其Manifest.xml文件如下:(由ADT创建,不做任何修改)

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.master"……><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme"><activityandroid:name="com.example.master.MainActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

第二步、定义奴隶工程,Manifest.xml如下(根activity加android:taskAffinity="com.example

.master")

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.slave"……><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name="com.example.slave.MainActivity"android:label="@string/app_name"android:taskAffinity="com.example.master"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><activityandroid:name=".AActivity"></activity><activity android:name=".BActivity"></activity></application></manifest>

第三步、结果

当我们启动宿主工程,按home键将宿主任务栈放到后台,然后启动奴隶工程,神奇的事情发生了:奴隶工程的MainActivity并没有被加载,而是显示的是宿主工程的MainActivity

第四步、 同样道理,反过来执行,我们首先启动奴隶工程,MainActivity-->AActivity-->BActivity,按home键,回到桌面启动宿主工程,结果并没有加载宿主工程的MainActivity,而是显示的是奴隶工程的BActivity.

第五步、结论

android:taskAffinity="com.example.master" 此属性指定了该activity所在的任务栈名称,如果系统当中已经存在指定的任务栈,那么该activity启动的时候会重新寄宿到宿主当中(这是android的官方说明,但是在实际的实践中发现,启动该activity的时候仅仅是将指定的任务栈推到前台,显示该任务栈最顶端的那个原activity,本activity并没有被创建,换言之,该activity的生命周期的相关方法并没有被执行);

如果系统当中没有指定的任务栈,那么系统会创建名为com.example.master 的任务栈,并将该activity放入到创建的任务栈当中。

第六步、诡异的事情:按照android官方文档的说明,宿主的activity当中应该要设置android:allow-

TaskReparenting="true",但是实验表明,不设置该属性亦可!

3. 与启动模式相结合的情景

3.1 android:taskAffinity 与 FLAG_ACTIVITY_NEW_TASK结合

(1)基本论断

如果加载某个Activity的intent,Flag被设置成FLAG_ACTIVITY_NEW_TASK时,它会首先检查是否存在与自己taskAffinity相同的Task,如果存在,那么它会直接宿主到该Task中,如果不存在则重新创建Task。

(2)测试。 
      我们首先写一个应用,它有两个Activity(Activity1和Activity2),AndroidManifest.xml如下:

<application

android:icon="@drawable/icon" android:label="@string/app_name"> 
    <activity android:name=".Activity1" 
                   android:taskAffinity="com.example.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);  
        }  
    }

//将activity1的启动模式改为new task ,并设置android:taskAffinity="com.example.task"

然后,我们再写一个应用MyActivity,它包含一个Activity(MyActivity),AndroidManifest.xml如下: 
<application

android:icon="@drawable/icon" android:label="@string/app_name"> 
    <activity android:name=".MyActivity" 
      android:taskAffinity="com.example.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(他的启动模式是new_task)。然后按返回键。 
           我们发现,我们进入Activity的顺序为Activity2->Activity1,而返回时顺序为Activity1->MyActivity。这就说明了一个问题,Activity1在启动时,重新宿主到了MyActivity所在的Task 中去了。

3.2 android:taskAffinity 与singleTask结合

直接给结论:

当一个应用程序加载一个singleTask模式的Activity时,首先该Activity会检查是否存在与它的taskAffinity相同的Task。

(1)、如果存在,那么检查是否实例化,如果已经实例化,那么销毁在该Activity以上的Activity并调用该Activity的onNewIntent()。如果没有实例化,那么该Activity实例化并入栈。

(2)、如果不存在,那么就重新创建Task,并入栈。

3.3 android:taskAffinity 与singleInstance结合

直接给出结论:

(1)、当一个应用程序加载一个singleInstance模式的Activity时,如果该Activity没有被实例化,那么就重新创建一个Task,并入栈,如果已经被实例化,那么就调用该Activity的onNewIntent;

(2)、singleInstance的Activity所在的Task不允许存在其他Activity,任何从该Activity加载的其它 Actiivty(假设为Activity2)都会被放入其它的Task中,如果存在与Activity2相同affinity的Task,则在该 Task内创建Activity2。如果不存在,则重新生成新的Task并入栈。

(3) 如果在奴隶应用application1当中定义两个activity,MainActivity和AActivity,将AActivity的启动模式设置为singleInstance,并设置其taskAffinity为com.example.master; 从MainActivity中启动AActivity,毫无疑问,此时会创建一个新的任务栈,名称是com.example.master,并将AActivity放置到栈中。然后将application1置于后台(按HOME键)。

打开宿主应用application2(默认的任务栈名称是com.example.master),此时惊奇地发现:此应用打开的是application1的AActivity,按后退键,退回到application2的MainActivity,由此可以看出,当声明为singleInstance的activity所在的任务栈被其他应用程序使用的时候,这个任务栈里面的原activity会丧失原来的singleInstance要求的一个activity在一个任务栈当中的属性,但是请注意:原来的这个activity始终是在栈顶的,后来加入的activity会都在这个activity的下面,但是还是按照栈的形式进出规则!

    (4)将上面的过程反过来,如果首先启动application2,系统当中存在了com.example.master 任务栈,然后启动SingleInstanceActivity,虽然他指定了taskAffinity,但是仍然不能将自己寄宿到com.example.master任务栈当中!他会重新开一个任务栈将自己放进去!

三、Activity的四种启动模式对Activity的启动有哪些影响?

重点说一下 singleTask,直接给结论:

1. 设置了"singleTask"启动模式的Activity,它在启动的时候,会先在系统中查找属性值affinity,等于它的属性值taskAffinity的任务栈是否存在存在;如果存在这样的任务栈,它就会在这个任务栈中启动,否则就会在新任务栈中启动。因此,如果我们想要设置了"singleTask"启动模式的Activity在新的任务中启动,就要为它设置一个独立的taskAffinity属性值。

2. 如果设置了"singleTask"启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经存在相应的Activity实例,如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity实例会位于任务的堆栈顶端中(这个过程会调用该Activity的onNewIntent())。

四、在Activity中使用startActivityForResult(intent, REQUESTCODE);和onActivityResult()

是否与被启动的Activity的launchMode有关?如果有关,有什么关系?

1.通常情况下,当launchMode设置为standard或者singleTop的时候,程序的执行流程如下所示

2.如果launchMode设置为singleTask或者singleInstance的时候,程序就会在setResult之前调用

onActivityResult(),这样就得不到从activity2返回的数据,所以需要注意!!!

转自:http://my.oschina.net/u/1865711/blog/289663

android 当中taskAffinity属性与launchMode相关相关推荐

  1. 【Android 应用开发】Activity 任务亲和性 taskAffinity 设置 ( taskAffinity 属性 )

    文章目录 I . 任务亲和性 ( taskAffinity ) 简介 II . 任务亲和性 ( taskAffinity ) 设置 III . 任务亲和性 ( taskAffinity ) 与 FLA ...

  2. android控件属性

    android控件属性 控件属性: android属性 Android功能强大,界面华丽,但是众多的布局属性就害苦了开发者,下面这篇文章结合了网上不少资料, 第一类:属性值为true或false an ...

  3. 【Android控件属性记录】

    #Android 控件属性记录 方便查找 控件属性: android属性 android功能强大,界面华丽,但是众多的布局属性就害苦了开发者,下面这篇文章结合了网上不少资料, 第一类:属性值为true ...

  4. android 软键盘的从属关系,Android控件属性大全

    控件属性: android属性 Android功能强大,界面华丽,但是众多的布局属性就害苦了开发者,下面这篇文章结合了网上不少资料, 第一类:属性值为true或false android:layout ...

  5. Activity的taskAffinity属性

    Activity的taskAffinity属性 - Android - ITeye技术网站 Activity的归属,也就是Activity应该在哪个Task中,Activity与Task的吸附关系.我 ...

  6. Android Activity标签属性

    Android Activity标签属性 Activity 是 Android 系统四大应用组件之一,用户可与 Activity 提供的屏幕进行交互,以执行拨打电话.拍摄照片.发送电子邮件等操作开发者 ...

  7. Android 高级面试-2:IPC 相关

    内容 IPC 就是指跨进程通信.IPC 相关的内容,涉及的主要有: 常见的 IPC 通信方式: Binder 相关: 两种序列化方式及其对比: 问题 IPC Android 上的 IPC 跨进程通信时 ...

  8. Android--应用开发3(Android layout XML属性)

    Android layout XML属性 转载:http://www.cnblogs.com/playing/archive/2011/04/07/2008620.html Layout对于迅速的搭建 ...

  9. 【错误记录】未安装该应用 ( 在 Android 12 之后 组件设置 android:exported=“false“ 属性 )

    文章目录 一.报错信息 二.解决方案 一.报错信息 报错信息 : 点击应用图标后 , 应用并未启动 , 并弹出 " 未安装该应用 " 提示信息 ; 二.解决方案 排查了一下相关地方 ...

最新文章

  1. 2020年PMCAFF大咖分享合集(有回放)
  2. 如何实现分类表统计数目和详情表数量同步
  3. boost::function_types::is_function_reference的测试程序
  4. 15分钟从零开始搭建支持10w+用户的生产环境(一)
  5. RS232与串口通信的4个注意事项详解
  6. springboot 监听所有异常_SpringBoot——目前Java开发最流行的框架(一)
  7. 助农两年销量千万 “李佳琦公益”实现“造血式”帮扶
  8. KL散度(双向KL散度) JS散度
  9. UEditor 实现新增“转换简体”和“转换繁体字”按钮功能
  10. word转化为html操作步骤
  11. Oracle优化器详解,通宵整理,透彻超详细
  12. (赠票)2021年佛山敏捷之旅暨第1届佛山DevOps社区Meetup
  13. 将sublime右下角永远改为HTML格式
  14. 情人辞职信 [搞笑,也来个好玩的乐一乐]
  15. [自习任我行]第二阶段任务跟踪1
  16. Win11安卓子系统(WSA)怎么卸载?
  17. 让吹牛都能全世界最棒
  18. 如何安装虚拟机linux
  19. 日常计算机桌面系统的维护,新手学电脑日常维护与故障排除
  20. docker容器无法访问宿主机报出 No route to host

热门文章

  1. 同步 异步 阻塞 非阻塞深入理解
  2. 迅为I.MX6Q开发板配不同分辨率不同尺寸液晶屏幕
  3. 【BZOJ3630】[JLOI2014]镜面通道 几何+最小割
  4. 出现could not find developer disk image解决办法和不受信任的开发者
  5. Installshield获取安装包版本的系统变量是IFX_PRODUCT_VERSION
  6. redis文档翻译_key设置过期时间
  7. jquery div拖动效果示例代码
  8. 通过 ANE(Adobe Native Extension) 启动Andriod服务 推送消息(二)
  9. 使用firefox遇到的问题
  10. [转] 初识Firebug(HTML查看和编辑、Javascript控制台、网络状况监视器)