taskAffinity 属性详解

taskAffinity 属性详解,第1张

本篇文章的目的是为了 搞清楚, 哪些情况下开启一个 Activity 会在新的 task 运行,哪些情况下会继续在原来的task 运行。

每个 Activity 运行时都有一个其归属的 task栈,我们可以用 activitygetTaskId() 的方法得到当前 activity 的taskId。 如果两个 activity 的 taskId 不同,则他们肯定不会属于同一个 task。

为了方便,我们在 Application 中注册生命周期回调,类似这样,我们打印出当前 activity 和其归属的 taskid。

taskAffinity 的使用方式如下,

如上图所示,taskaffinity 可以单独对一个 activity 使用,代表该 activity 所想归属的 task;

也能对application 使用,代表该 application 内声明的所有 activity 都归属于这个task。

如果 activity 组件没有声明 taskAffinity 的话,该 activity 的 taskAffinity 属性也是有默认值的。如果 application 指定了 taskAffinity 值,默认值就是 application 指定的 taskAffinity 值;如果 application 未指定的话,默认值就是 manifest 中声明的包名(package 对应的字符串)。

Android 手机的任务列表就是根据不同 task d出的,我们可以根据任务管理器有几个 item 图标,来知道我们开启了几个 task。

是不是我指定了一个 Activity 的 taskAffinity 值(跟包名不同),运行该 Activity 时,是否就会新开这个 task栈呢?

答案是否定的, 一个 Activity 运行时所归属的task,默认是启动它 的那个Activity 所在的 task (下文将会验证)。

taskAffinity 单独使用并不会生效。

要想其生效,需要配合其他属性使用,或者配合 IntentFLAG_ACTIVITY_NEW_TASK,或者配合

allowTaskReparenting 。使用时用其中的一个就行,下面将详细介绍这两个属性。

IntentFLAG_ACTIVITY_NEW_TASK 使用方式如下,

首先说下这个规则是根据测试结果反推出来的,不对之处还还请指出(捂脸。。。)

==当 AMS 发现启动了一个带有 FLAG_ACTIVITY_NEW_TASK 标签的 Activity 时,会先去寻找当前是否存在这个 Activity 的 task 值(这个值具体是什么可看 知识点2),如果不存在的话,就会创建该task,如果存在就省去了创建 task 这个步骤。然后在把要启动的 Activity 添加到 task 中。

下面开始我们的测试,测试结果为过滤后的log日志,并给出相应分析。

我们假定都是 Activity A 跳转到 Activity B 中,A没有指定 taskAffinity 属性,B 的launchMode 为standard。

可以验证:一个Activity 归属的task 是由 启动它的 Activity 所决定的。

可以验证,一个 Activity 的默认 task 值就是 manifest 定义的包名。

可以验证:不指定 FLAG_ACTIVITY_NEW_TASK的话, 即使 taskAffinity 不同,一个Activity 归属的task 仍然是由 启动它的 Activity 所决定的。

可以验证:即使 使用了 FLAG_ACTIVITY_NEW_TASK,但由于两者的 taskAffinity 相同,所以仍然不会开启一个新的task。

可以验证:开启一个新task 的条件是 FLAG_ACTIVITY_NEW_TASK 和 taskAffinity 不同 缺一不可。

可以得出:未指定 FLAG_ACTIVITY_NEW_TASK 和 新的 taskAffinity 时,这两种启动模式对task 没有影响

可以得出:

singleinstance 启动模式本身就是会开启一个新的task 装载 这个Activity,且task 中只有这一个 Activity。

经判断得知,AMS 是先对 launchMode 做判断 再处理 FLAG_ACTIVITY_NEW_TASK 的,如果是 singleinstance ,则会直接开启一个task。

上面七个 case 均是在同一个app 内的,现在考虑跨进程调用的情况,A在 app1,B在app2, 此时 B 的默认 task 肯定是和 A 不同的

我们可以通过隐式启动的方式启动B,B 仍然是标准启动模式。

类似这样

++下文 所有的 App1的log标识为 MyApplication,App2 的标识为 MyApplication2。++

可以得出:case 8 与 case 3 的本质是相同的,仅仅是 A 和 B 的taskA 属性不同,所以没有开启新的task。

我们还可以看出,task 是可以跨进程的,即一个 task 中的 Activities 是可以运行在不同的进程中的。(关于 A 和 B 不在同一个进程读者可自行验证)

可以得出:case 9 与 case 5 的本质是相同的。

至此,Intent 的 FLAG_ACTIVITY_NEW_TASK 属性 应该算是讲解清楚了。

我们还可以得出一个有意思结论,那就是 AMS 分配的taskid 是线性递增的,每次开启一个新的task ,taskid 永远都是 +1 的 *** 作。

测试该属性的话,应该先把 FLAG_ACTIVITY_NEW_TASK 属性去掉。

allowTaskReparenting 这个属性指的是一个 Activity 运行时,可以重新选择自己所属的task。基本是在跨app 间调用时,我们在上面的case 8 的基础上,对 Activity 做如下修改

当 A 启动 B 时,这时虽然是在两个进程中的,但其归属的task 是同一个,这时我们回到后台,在桌面点击 B 的应用图标,我们会发现 log 日志如下:

其中 MyApplication 代表 app1,MyApplication2代表 app2。

log 日志如下:

此 case 正好验证之前的解析规则,若 Activity taskAffinity指定的task 已经存在,是会复用之前的task,而不会再重新创建一个新的task。

最近开发遇到的一些查询用例,简单记录下

一、定义Repository

@Repository

public interface TransTaskManager extends JpaRepository<TransTask, Long>, JpaSpecificationExecutor<TransTask> {}

二、Repository查询语句

1,对象作为参数传输

@Modifying

@Transactional

@Query("update TransTask t set tflowStatus =:#{#transTaskflowStatus} where tflowStatus =:#{#oldStatus}")

int updateFlowStatus(@Param("transTask") TransTask transTask, @Param("oldStatus") int oldStatus);

2,字符串作为参数:

@Modifying

@Transactional

@Query("update TransTask t set ttransId =:transId where ttaskId =:taskId")

int updateTransId(@Param("transId") String transId, @Param("taskId") String taskId);

3,参数定位

@Query(" from TransTask t where ttaskId = 1 and ttaskName like 2 and tflowStatus=100 and tisDelete=2 ")

Page<TransTask> queryByParams(@Param("taskId") String taskId, @Param("taskName") String taskName, Pageable pageable);

4,原生sql

@Query(value = "select tplayUrl from ty_trans_task t where ttaskId =:taskId", nativeQuery = true)

String getPlayUrls(@Param("taskId") String taskId);

5,Example_实例查询

Person person = new Person();

personsetFirstname("Dave"); //Firstname = 'Dave'

ExampleMatcher matcher = ExampleMatchermatching() withMatcher("name", GenericPropertyMatchersstartsWith()) //姓名采用“开始匹配”的方式查询

withIgnorePaths("int"); //忽略属性:是否关注。因为是基本类型,需要忽略掉

Example<Person> example = Exampleof(person, matcher); //Example根据域对象和配置创建一个新的ExampleMatcher

6,specification查询

1、嵌套子流程的子流程,子流程嵌入在它的主流程(上图命名为入口流程,主流程是指整个流程图);

2、嵌套子流程的子流程没有流程实例id,主流程有流程实例Id;(流程实例id是指,启动流程之后,会生成的id)

3、嵌套子流程节点区别于任务节点,嵌套子流程没有任务id(taskId),任务节点有任务id(taskId),但,任何类型的节点都有执行id(Id)。(任务id,节点类型为UserTask的,并节点在被触发之后,生成的id)

4、不能人为的启动嵌套子流程的子流程

以上就是关于taskAffinity 属性详解全部的内容,包括:taskAffinity 属性详解、SpringJPA的动态查询、flowable子任务没有taskkey等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9398746.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存