activity的singletask模式以及taskaffinity属性

本文探讨了Android中activity的singletask模式及taskaffinity属性。通过实例展示了当两个activity的taskaffinity相同时,即使设置为singletask,也不会新开任务栈,而是位于原有栈中。同时,总结了singletask模式下activity启动的两种情况,强调了设置独立taskAffinity的重要性。此外,提到了返回键操作与ActivityRecord栈管理的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

以及 http://blog.youkuaiyun.com/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有关了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值