关于Android TaskAffinity的那些事儿
正常情况下,如果应用已经启动,并将应用切到后台,在通知栏中调起页面时,该应用的Task首先会被调起,然后会将我们的Activity显示在这个Task的顶端。手机百度的通知栏里面有一个快速搜索栏,无论什么情况下,点击之后都会直接弹出搜索页面,透明背景后显示的是桌面。怎么来实现这个功能呢?这就要提到我们的主角TaskAffinity了。
什么是affinity?
affinity是指Activity的归属,Activity与Task的吸附关系,也就是该Activity属于哪个Task。一般情况下在同一个应用中,启动的Activity都在同一个Task中,它们在该Task中度过自己的生命。每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task。如果一个Activity没有显式的指明taskAffinity,那么它的这个属性就等于Application指明的taskAffinity,如果Application也没有指明,那么该taskAffinity的值就等于应用的包名。我们可以通过在元素中增加taskAffinity属性来为某一个Activity指定单独的affinity。这个属性的值是一个字符串,可以指定为任意字符串,但是必须至少包含一个”.”,否则会报错。
affinity在什么场合应用呢?
1.根据affinity重新为Activity选择宿主task(与allowTaskReparenting属性配合使用)
allowTaskReparenting用来标记Activity能否从启动的Task移动到taskAffinity指定的Task,当把Activity的allowTaskReparenting属性设置成true时,Activity就拥有了一个转移所在Task的能力。具体点来说,就是一个Activity现在是处于某个Task当中的,但是它与另外一个Task具有相同的affinity值,那么当另外这个任务切换到前台的时候,该Activity就可以转移到现在的这个任务当中。allowTaskReparenting默认是继承至application中的allowTaskReparenting=false,如果为true,则表示可以更换;false表示不可以。
举一个形象点的例子,比如有一个天气预报程序,它有一个用于显示天气信息的Activity,allowTaskReparenting属性设置成true,这个Activity和天气预报程序的所有其它Activity具体相同的affinity值。这个时候,你自己的应用程序通过Intent去启动了这个用于显示天气信息的Activity,那么此时这个Activity应该是和你的应用程序是在同一个任务当中的。但是当把天气预报程序切换到前台的时候,这个Activity会被转移到天气预报程序的任务当中,并显示出来。如果将你自己的应用切换到前台,发现你自己应用Task里的那个Activity消失了。
2.启动一个Activity过程中Intent使用了FLAG_ACTIVITY_NEW_TASK标记,根据affinity查找或创建一个新的具有对应affinity的task。
当调用startActivity()方法来启动一个Activity时,默认是将它放入到当前的任务当中。但是,如果在Intent中加入了FLAG_ACTIVITY_NEW_TASK
flag的话,情况就会变的复杂起来。首先,系统会去检查这个Activity的affinity是否与当前Task的affinity相同。如果相同的话就会把它放入到当前Task当中,如果不同则会先去检查是否已经有一个名字与该Activity的affinity相同的Task,如果有,这个Task将被调到前台,同时这个Activity将显示在这个Task的顶端;如果没有的话,系统将会尝试为这个Activity创建一个新的Task。需要注意的是,如果一个Activity在manifest文件中声明的启动模式是”singleTask”,那么他被启动的时候,行为模式会和前面提到的指定FLAG_ACTIVITY_NEW_TASK一样。
那么,有了上面的知识,我们应该可以实现开头提到的功能了。
功能的实现
首先,在mainifest中配置我们的Activity,
<activity
android:name="com.test.TestActivity"
android:configChanges="orientation|keyboard|keyboardHidden"
android:exported="true"
android:taskAffinity="com.test.TestActivity"
android:screenOrientation="portrait"/>
然后增加通知栏的逻辑
NotificationManager mNotifManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification();
notification.icon = R.drawable.icon;
notification.flags = Notification.FLAG_ONGOING_EVENT;
notification.flags = Notification.FLAG_AUTO_CANCEL;
notification.flags = Notification.FLAG_NO_CLEAR;
RemoteViews mContentView = new RemoteViews(mContext.getPackageName(),
R.layout.notification_test);
notification.contentView = mContentView;
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(mContext, TestActivity.class);
PendingIntent pendingIntent =PendingIntent.getActivity(mContext, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
notification.contentView.setOnClickPendingIntent(R.id.rl_notification,
pendingIntent);
mNotifManager.notify(NOTIFYID, notification);
现在我们可以实现开头提到的那种效果了。但是,我发现最近任务中会有两个我们应用的图标,看起来像是启动了两个我们的应用,非常奇怪,而实际上是因为我们的应用启动了两个Task。我们可以通过在manifest此Activity的属性中增加Android:excludeFromRecents=”true”。这属性用于设置由该Activity所启动的任务是否应该被排除在最近使用的应用程序列表之外。也就是说,当这个Activity是一个新任务的根节点时,这个属性决定了这个任务是否会显示在用户最近使用的应用程序列表中。如果设置为true,则这个任务会被排除在列表之外,为false,则表示会包含在最近使用的应用列表中。默认值是false。
场景验证
前提:将页面背景设置为半透明。
1、未使用affinity
如果应用没有启动,点击通知栏,当前Activity被调起,透明背景后显示为桌面。
如果应用已经启动,点击通知栏,应用的Task调到前台,当前Activy显示在该Task的顶端。
2、使用affinity
无论应用是否已经启动,点击通知栏,当前Activity都会被调起,透明背景后显示为桌面。
两种情况下,看最近任务栏,都只显示一个应用图标。
这样就实现了我们想要的效果。
关于Android TaskAffinity的那些事儿的更多相关文章
- Android -- taskAffinity
每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task.如果一个Activity没有显式的指明该Activity的taskAffinity,那么它的这个属性就等于Ap ...
- 【Bugly干货】关于 Android N 那些你不知道的事儿
今年3月,Google 破天荒提前半年发布了 Android N 开发者预览版.当然,作为一个不合格的谷粉并没有第一时间体验安装,因为至今仍然能够回忆起来去年今日此门中(雾)兴冲冲刷了 Android ...
- Android+Handler+Thread 那些事儿
前言,才开始学安卓十几天,不料被线程挡住了前进的步伐,因为之前操作系统课程并没有认真听老师讲课,导致现在理解这些抽象的东西有些小困难.没关系,苦学之路,总会碰到坎坷,这里也给那些迷失在Android之 ...
- Android关于Task的一些实践之SingleTask, SingleInstance和TaskAffinity
上一篇文章粗略地介绍了一下关于Android中Task的基本知识.只是实践才是检验真理的唯一标准,所以.今天就来试验一下Task中的launchMode是否真的实现了文档所说的那样. 首先.定义三个A ...
- [转]Android的taskAffinity
Activity的归属,也就是Activity应该在哪个Task中,Activity与Task的吸附关系.我们知道,一般情况下在同一个应用中,启动的Activity都在同一个Task中,它们在该Tas ...
- android 启动模式介绍
Android启动模式 (1)Task:与Android系统是个多任务的系统中的任务是不同的.后者更倾向于多进程和多线程来说的,而这里的任务与application(应用程序)和activity(活动 ...
- Android入门(六):Android控件布局属性全解
第一类:属性值为true或falseandroid:layout_centerHrizontal 水平居中 (Hrizontal表示水平)android:layout_centerVertical 垂 ...
- Android 启动模式及常用的Intent的Flag
LaunchMode 在声明Activity的xml中指定 android:launchMode="xxx" standard 标准模式.这是系统默认的模式,每次启动Activit ...
- 【Bugly安卓开发干货分享】Android APP 快速 Pad 化实现
项目背景 采用最新版本手机 APP(之后称为 MyApp)代码,实现其 Pad 化,为平板和大屏手机用户提供更好的体验.为实现 MyApp 的 Pad 化工作,需要我们首先来了解一下 MyApp 项目 ...
随机推荐
- Python+Selenium练习篇之20-处理Alert弹窗
本文来介绍如何通过Selenium方法去处理网页Alert弹窗,和处理iframe类似,都是通过switch_to方法.这里还是没有找到合适的alert弹窗网站,我们就自己创建一个吧,前面文章介绍了如 ...
- Python-S9-Day116——Flask框架相关
01 内容回顾 02 Flask框架:路由和视图(一) 03 Flask框架:路由和视图(二) 04 Flask框架:路由和视图(三) 05 Flask框架:路由和视图(四) 06 Flask框架:s ...
- Wordpress 文章添加副标题
后台编辑区添加自定义副标题字段 /** * Add Subtitle in all post */ function article_subtitle( $post ) { if ( ! in_arr ...
- Mac Xnip 截图软件快捷键设置
点击 Shortcut 后输入你需要的截图快捷键
- python矩阵和向量的转置问题
numpy有很多方法进行转置,这里由于时间和精力限制(主要是我实在比较懒,有一个基本上一直能使的,就懒得看其他的了),其他方法我没研究,这里我总结的东西,如果有问题,欢迎各路大佬拍砖 一.创建矩阵: ...
- LFTP下载远程文件
拓展阅读: https://linux.cn/article-5460-1.html
- mac最新系统安装beego出现kiil 9
(内容来自:http://www.oschina.net/question/2626413_2237311) 应该是最新mac OS 12.04的锅. 现在的解决办法是回退bee到以前版本. cd $ ...
- 【Luogu】P3320寻宝游戏(Splay)
题目链接 其实这题用Set就完事了但我不会Set 智商-=inf 求虚树上所有边权和的两倍. 具体方式就是splay把所有在虚树上的点存一下,(按照DFS序排序的)每次插入/删除会更新前驱和它.后继和 ...
- socket实例C语言:一个简单的聊天程序
我们老师让写一个简单的聊天软件,并且实现不同机子之间的通信,我用的是SOCKET编程.不废话多说了,先附上代码: 服务器端server.c #include <stdio.h> #incl ...
- Moscow Pre-Finals Workshop 2016. Japanese School OI Team Selection. 套题详细解题报告
写在前面 谨以此篇题解致敬出题人! 真的期盼国内也能多出现一些这样质量的比赛啊.9道题中,没有一道凑数的题目,更没有码农题,任何一题拿出来都是为数不多的好题.可以说是这一年打过的题目质量最棒的五场比赛 ...