关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » 安卓开发 »Android taskAffinity属性使用详解

    Android taskAffinity属性使用详解

    2014-11-24 00:00:00 出处:徐明璐的博客
    分享

    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.winuxxan.affinity true

    application2 Activity2 com.winuxxan.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.winuxxan.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.winuxxan.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并入栈.

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    严重缩水!NVIDIA将推中国特供RTX 5090 DD:只剩24GB显存

    00:17

    技术热点

    在windows 7桌面右键菜单上添加直接卸载USB设备的快捷菜单选项

    12个Java长久占居主要地位的原因

    SQL Server创建数据库的命令

    SQL Server 带列名导出到excel的实际操作

    MySQL字符串连接函数repeat()

    使用SQL Server日志转移实现高可用性

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。