TaskAffinity

     首先来看一下android 官方对taskAffinity的描述

android:taskAffinity
The task that the activity has an affinity for. Activities with the same affinity conceptually belong to the same task (to the same "application" from the user's perspective). The affinity of a task is determined by the affinity of its root activity.
The affinity determines two things — the task that the activity is re-parented to (see the allowTaskReparenting attribute) and the task that will house the activity when it is launched with the FLAG_ACTIVITY_NEW_TASK flag.

By default, all activities in an application have the same affinity. You can set this attribute to group them differently, and even place activities defined in different applications within the same task. To specify that the activity does not have an affinity for any task, set it to an empty string.

If this attribute is not set, the activity inherits the affinity set for the application (see the <application> element's taskAffinity attribute). The name of the default affinity for an application is the package name set by the <manifest> element.

我来大致翻译一下:taskAffinity就是用来描述activity所在的task的一种属性。如果activity的taskAffinity的属性如果相同的话,那他们就在相同的task中。默认情况下,activity的taskAffinity的属性就是程序包名。(注意:这句话不等于taskAffinity属性不一样的就在不同的task中)。接下来给出一个很简单的例子:

  AndroidManifest.xml的内容如下 :

  

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.loadresource"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity<span style="font-family: Arial, Helvetica, sans-serif;">           </span>
<pre name="code" class="html">            android:taskAffinity="a"
            android:allowTaskReparenting="true"
android:name=".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:taskAffinity="b" android:allowTaskReparenting="true" android:label="@string/app_name" android:name=".MainActivity2" ></activity> </application></manifest>

  具体代码就是一个HelloWord的例子,具体只给出启动Activity的过程: 

    Intent intent=new Intent();                
    intent.setClass(MainActivity.this,MainActivity2.class);
     startActivity(intent);	
然后分别在两个activity中输出各自所在的task的taskID。



从之前的文档中我们知道,activity的默认taskAffinity就是包名。显然两个activy的taskAffinity的属性不同,但是它们在同一个栈中。那怎样让他们在不同的栈中 ?可以在启动的时候加上这样一行代码:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
我们继续来看结果:


可以看到在不同task中了,当然也可以配置相应的启动模式,比如说singleTask。

接下来让我们来看本文的重点,如果在两个不同的application中,存在两个activity有相同的taskAffinity.

我们还是先从demo开始。applicationA的Mainifest文件就如同上述。下面来设置applicationB的Mainnifest文件。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.loadresource2"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
             android:taskAffinity="a"
            android:allowTaskReparenting="true" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
可以看到两个application的第一个要启动的activity的taskAffinity属性相同。让我们先分别运行这两个运行程序?No,先让大家猜一下结果,(假设系统已经安装了这两个application )先运行applicaitonA,等完全显示出view后,接着按home键,然后再运行applicationB,会出现怎样的情况呢 ?大部分人肯定会说:肯定显示applicationB中的MainActivity界面啊。但是很遗憾,结果并不是这样! 你会感到很吃惊吧。

  首先我们来运行applicatitionA。

 接着按home。然后启动applicationB,奇怪的事情发现了怎么又是


接着我按返回,咦,咋直接结束了,直接回到home界面。(不信的朋友可以去试一下)(接下来的博客我会在源码分析中重点说明这一点)

然后我又调整了一下applicationA的Mainifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.loadresource"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".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:taskAffinity="a"
            android:allowTaskReparenting="true"
            android:label="@string/app_name" 
            android:name=".MainActivity2"            
       ></activity>
    </application>

</manifest>
从配置文件可以知道,MainActivity2中的taskAffinity和applicationB中的MainActivity相同。其中MainActivity2是MainActivity启动的。接下来我们重复上面的操作:

得到MainActivity2运行界面:


然后按下home键,运行applicationB,这个时候,我当时用了两个手机做测试,发现结果出人意料,结果完全不一致。一个是显示上面这张图,另外一个是显示applicationB的第一个activity的画面。这是因为有些rom定制了自己对栈的管理。但是从下面一篇博客我将会从源码进行分析这个过程。


  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值