activity的singletask模式以及taskaffinity属性

来源:互联网 发布:mac按什么键切换系统 编辑:程序博客网 时间:2024/05/21 09:28

网上讲解activity的launchmode时,对singletask大部分的说明都是:“singleTask”和”singleInstance”则限制只生成一个实例,并且是task的根元素。

这个的后半句是错的,幸好看到了几篇专门讲解singletask模式的文章。

推荐:http://blog.csdn.net/luoshengyang/article/details/6714543 这个是老罗的

以及 http://blog.csdn.net/wdaming1986/article/details/7304191


从singletask讲起,就不得不提到taskaffinity属性。taskaffinity顾名思义,就是描述activity的类型之间的归附关系

每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task。如果一个Activity没有显式的指明该 Activity的taskAffinity,那么它的这个属性就等于Application指明的taskAffinity,如果 Application也没有指明,那么该taskAffinity的值就等于包名。而Task也有自己的affinity属性,它的值等于它的根 Activity的taskAffinity的值。如下:

        <activity            android:name="com.yj.testuserfeed.UserFeedOne"            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="UserFeedTwo"            android:launchMode="singleTask"            android:taskAffinity="com.testaffinity" >        </activity>

我的包名是com.yj.testuserfeed;然后在mainactivity中去启动UserFeedTwo这个Activity。

protected void onResume() {super.onResume();mName.setText(TAG+"---"+this+"----"+getTaskId()+"---"+isTaskRoot());}


此时可以看到两个activity位于不同的栈中,121为taskid,true表示为task根元素。




当我把第一个activity的taskaffinity也设置成com.testaffinity时,在第二个activity启动后,显示此activity不为根元素,而且所在的taskid和第一个activity相同。

当把UserFeedOne的taskaffinity缺省,UserFeedTwo的taskaffinity设置为包名,即com.yj.testuserfeed时,两者还是位于同一栈中,说明缺省的taskaffinity为application的包名。

由上可知,如果两个activity的taskaffinity相同时,即使UserFeedTwo设置为singletask,也不会新开一个栈来存放,而是还位于原来的栈中,即使在intent中设置了i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);也不行。


从上面的实验来看,验证了老罗的话:

至此,我们总结一下,设置了"singleTask"启动模式的Activity的特点:

        1. 设置了"singleTask"启动模式的Activity,它在启动的时候,会先在系统中查找属性值affinity等于它的属性值taskAffinity的
任务存在;如果存在这样的任务,它就会在这个任务中启动,否则就会在新任务中启动。因此,如果我们想要设置了"singleTask"启动模式
的Activity在新的任务中启动,就要为它设置一个独立的taskAffinity属性值。
        2. 如果设置了"singleTask"启动模式的Activity不是在新的任务中启动时,它会在已有的任务中查看是否已经存在相应的Activity
实例,如果存在,就会把位于这个Activity实例上面的Activity全部结束掉,即最终这个Activity实例会位于任务的堆栈顶端中。


TaskAffinity和几个launchmode以及Intent.FLAG_ACTIVITY_NEW_TASK等启动模式,这三者之间的关系说起来很复杂,有各种各样的组合,不过其实这些都和AMS中对activity的管理有关。

比如实验的时候遇到了一个有意思的情况,用了三个activity,A为main入口,B为singletask并且未设置taskaffinity,C为singleInstance,每个activity都有三个按钮可以进入其他activity,此时如果是A—>B—>C—>B时,按返回键的顺序为B—>A—>C;说明android的返回键来finish activity时即为出栈的过程,这个就和AMS中的ActivityRecord和mHistory有关了。


原创粉丝点击