Activity的几种启动模式

Activity的几种启动模式,第1张

一先理解栈的概念(放置Activity实例的容器)

1Task(线性表)

任务栈Task,用来放置Activity实例的容器,先进后出,主要有2个基本 *** 作:压栈和出栈,其所存放的Activity是不支持重新排序的, 只能根据压栈和出栈 *** 作更改Activity的顺序

2app启动时,系统会为它默认创建一个对应的Task,用来放置根Activity

ps: Activity之间可以相互启动,当前应用的Activity可以去启动其他应用的Activity(相机),那么就是说栈的功能可以把其它app的activity加入到自己app的栈里

所以Task可以理解为负责管理所有用到的Activity实例的栈,但是android50之后 跨进程调用activity,这个activity会被放入到一个新的栈中。

二启动模式(只能根据压栈和出栈 *** 作更改Activity的顺序,所以是启动模式是以哪种姿势入栈)

通过在AndroidManifest文件中的属性andorid:launchMode来设置或者通过Intent的flag来设置

1standard(常规姿势入栈)

默认模式。在这个模式下,都会默认创建一个新的实例。因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加。应用场景:绝大多数Activity。

2singleTop(栈顶复用姿势入栈)==FLAG_ACTIVITY_SINGLE_TOP

栈顶复用模式,如果要开启的activity在任务栈的顶部已经存在,就不会创建新的实例,而是调用 onNewIntent() 方法。避免栈顶的activity被重复的创建。应用场景:在通知栏点击收到的通知,然后需要启动一个Activity,这个Activity就可以用singleTop,否则每次点击都会新建一个Activity。某个场景下连续快速点击,启动了两个Activity。如果这个时候待启动的Activity使用 singleTop模式也是可以避免这个Bug的。

3singleTask(栈内复用姿势入栈)==FLAG_ACTIVITY_CLEAR_TOP

栈内复用模式, activity只会在任务栈里面存在一个实例。如果要激活的activity,在任务栈里面已经存在,就不会创建新的activity,而是复用这个已经存在的activity,调用 onNewIntent() 方法,并且清空这个activity任务栈上面所有的activity( CLEAR_TOP回到栈顶 )。应用场景:大多数App的主页。对于大部分应用,当我们在主界面点击回退按钮的时候都是退出应用,那么当我们第一次进入主界面之后,主界面位于栈底,以后不管我们打开了多少个Activity,只要我们再次回到主界面,都应该使用将主界面Activity上所有的Activity移除的方式来让主界面Activity处于栈顶,而不是往栈顶新加一个主界面Activity的实例,通过这种方式能够保证退出应用时所有的Activity都能报销毁。

4singleInstance(不入栈)

单一实例模式,整个手机 *** 作系统里面只有一个实例存在。不同的应用去打开这个activity 共享公用的同一个activity。他会运行在自己单独,独立的任务栈里面,并且任务栈里面只有他一个实例存在。应用场景:呼叫来电界面。这种模式的使用情况比较罕见,在Launcher中可能使用。或者你确定你需要使Activity只有一个实例。建议谨慎使用。

5FLAG_ACTIVITY_NO_HISTORY

Activity使用这种模式启动Activity,当该Activity启动其他Activity后,该Activity就消失了,不会保留在Activity栈中。

1getTaskId();获取当前activity所处的栈

2同一个应用程序中的activity的亲和性一样(taskAffinity),也就是说 Actviitya intent时setFalg(IntentFLAG_ACTIVITY_NEW_TASK)到Activityb 但是Actviitya和Activityb 还是一个栈

在不同的应用中跳转才会创建新的Task。

3在Activity上下文之外启动Activity需要给Intent设置FLAG_ACTIVITY_NEW_TASK标志,不然会报异常。

四 FLAG_ACTIVITY_CLEAR_TASK(必须和FLAG_ACTIVITY_NEW_TASK一起使用)

清空栈内activity,只留下这个activity

1、创建测试表,

create table test_task(taskID varchar2(20),taskName varchar2(200));

create table test_person(personID varchar2(20),personName varchar2(200));

create table test_task_person(taskID varchar2(20),personID varchar2(200));

2、插入测试数据;

insert into test_task values (101,'Task_101');

insert into test_task values (102,'Task_102');

insert into test_task values (103,'Task_103');

insert into test_person values (1001,'Person_1001');

insert into test_person values (1002,'Person_1002');

insert into test_person values (1003,'Person_1003');

insert into test_task_person values (101,1001);

insert into test_task_person values (101,1002);

insert into test_task_person values (102,1001);

insert into test_task_person values (102,1003);

insert into test_task_person values (103,1001);

insert into test_task_person values (103,1003);

commit;

3、查询1,查询每个任务对应的担当者;select t, bpersonName from test_task_person t, test_person b where tpersonID = bpersonID;

4、查询2,查询每个人承担的任务;select t, btaskName from test_task_person t, test_task b where ttaskID = btaskID;

一 表结构
前面一章的关于spring的demo,我们配置好数据库,第一次会自动为我们给的数据库生成对应的表,但是表实在是太多,网上一些资料比较过时,举个例子有的材料列举了二十几个,但实际上我这个版本不止,我随便数了一下都七十几个了。
还有就是Flowable的表很多创建的名字也是为了能“见词知意”,会有前缀或者类似“词根”之类的来拼接。同样很多人的资料博客关于这些,好像抄的是同一份一样。都是常见的几个,你想DMN这些都没人提及。
这里以我现在的flow able表结构做一个大概的总结介绍:
首先上个图
在这里插入描述
在这里插入描述
大概表名分三段
XXX_XXX_XXXX
第一段
第一段以ACT_APP_APPDEF 和 FLW_CHANNEL_DEFINITION为例子
ACT代表的Activiti 毕竟是同一批人另起的炉灶,另一方面遵循的都是BPMN还要考虑到兼容人家,方便客户转移过来。
ACT_APP_APPDEF看字面意思是应用定义表。
FLW估计就是Flowable的自己的时缩写。
FLW_CHANNEL_DEFINITION这个的意思是,Flowable支持JMS、Kafka和RabbitMQ源和目标,但也可以使用其他适配器类型进行扩展。部署通道定义时,新定义将插入到FLW_CHANNEL_DEFINITION表中,表明翻译过来Flowable的渠道定义。
第二段
APP指的是应用
CO 我认为是connection连接的意思,我看内容大部分跟连接数据库这些相关
act_cmmn_:CMMN流程引擎数据
act_dmn_ : DMN流程引擎
act_evt_log: 事件日志
act_fo_:表单引擎数据
act_ge_: 通用数据
act_hi_:表包含历史数据
act_id_:存储与用户身份相关数据
act_prodef_info:流程定义的信息
act_re_: 流程定义相关数据的存储库
act_ru__:流程实例运行时数据,流程结束删除数据
第三段
实际上这一段,如果不是太长,有的很多就是整个单词,DEF就是定义的意思,DECISION就是描述的意思,JOB就是任务等,总之就是相对第二段比较容易看出来,像DMN谁能一眼看出来到底是什么。
怎么说呢,太多了这些,基本是遇到问题看那个,记住几个常用的就可以了,不一定都能接触的到,同样也能想象出这个工作流设计要多复杂,我们自己的一些审批任务,基于人家的又是都觉得有点绕,何况人家提供的基础的服务支持设计的。
流程变量
流程实例执行时,要保存数据,这些都被称作变量variable,流程变量分两种:运行时变量,历史变量。
运行时变量
就是还在运行的流程实例的持有的变量,流程实例结束了,这个实例的变量也就在这个表的被剔除了,变成历史变量。
运行时变量,存的表是act_ru_variable
#定义时就设置了变量
ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map<String, Object> variables);
#或者运行中设置变量
void setVariable(String executionId, String variableName, Object value);
void setVariableLocal(String executionId, String variableName, Object value);
void setVariables(String executionId, Map<String, extends Object> variables);
void setVariablesLocal(String executionId, Map<String, extends Object> variables);
#都运行时变量,这个如果实例运行完了就查不到留在这个表
Map<String, Object> getVariables(String executionId);
Map<String, Object> getVariablesLocal(String executionId);
Map<String, Object> getVariables(String executionId, Collection<String> variableNames);
Map<String, Object> getVariablesLocal(String executionId, Collection<String> variableNames);
Object getVariable(String executionId, String variableName);
<T> T getVariable(String executionId, String variableName, Class<T> variableClass);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
历史变量
历史变量其实算是比较多的,一般来说除非是运行时实例,自己这边出问题直接看问题看的是运行时的变量(其实这个也能在历史变量中看到)。如果是对已经审批完的流程有疑问基本看的都是历史变量。
历史变量,存的是act_hi_varinst表act_hi_varinst
实例创建,历史变量有对应的变量,实力结束依旧能找到,可以说时变量的“永久”。
historyServicecreateHistoricVariableInstanceQuery()
processInstanceId("XXX")
orderByVariableNamedesc()
list();
1
2
3
4
5
1
2
3
4
5
重要字段介绍
(1)processDefinitionId 流程定义Id
(2)processDefinitionKey 流程定义Key
(3)processDefinitionName 流程定义名称
(4)procInstId 流程实例Id
(5)taskId 任务Id
(6)executionId 执行Id
前三个都是流程定义的,就是说我们发起流程通过ID,key,name这些来发起流程。
你发起流程就会有一个实例,大概的例子就是Java的calss和对象一样,class定义了整体的结构和意义,但是真正用的还是被new出来并且赋值的一个个对象。流程就是class,你定义好了,去处理一个个具体的场景时,就是一个个具体的对象,也就是流程实例。
(4)(5)(6)其实是一级一级的关系,一个流程实例ID可以对应多个执行ID,一个执行对应多个task(这个我后面验证一下,暂时我这边也不太确定),反正大多数材料形容三个的关系是“面-》线-》点”。
表单
表单其实就是定义的部分,就是通过一种简单的方式去构造一个flowable流程引擎。
(看下面的官网最新的英文解释,更对味,可以参照后面某个版本的flowable的中文手册翻译)
The Flowable Form engine is structured in a very similar way to the Flowable process engine As a result parts of the documentation have a resemblance with their process engine counterpart
在这里插入描述
在这里插入描述
在实际业务中,流程伴随着各种各样的表单,Flowable引擎将表单数据统一作为流程变量存入变量表中。所以,对于Flowable引擎,可以完全独立于表单运行,因为可以用流程变量替代表单数据。
但一般的,我们需要结构化的数据,表单仍然是我们推荐的用法。
表单:内置表单,外部表单
内置表单
以请假为例,XML内容
<process id="leave" name="请假流程-内置表单">
<startEvent id="start">
<extensionElements>
<flowable:formProperty id="startDate" name="请假开始事件" type="date"
datePattern="dd-MMM-yyyy" required="true" readable="true" writeable="true"/>
<flowable:formProperty id="endDate" name="请假结束事件" type="date"
datePattern="dd-MMM-yyyy" required="true" readable="true" writeable="true"/>
<flowable:formProperty id="reason" name="请假原因" type="string"
required="true" readable="true" writeable="true"/>
<flowable:formProperty id="leaveType" type="enum" name="请假类型">
<flowable:value id="personalLeave" name="事假" />
<flowable:value id="annualLeave" name="年假" />
</flowable:formProperty>
</extensionElements>
</startEvent>
</process>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
StartFormData FormServicegetStartFormData(String processDefinitionId)
1
1

TaskFormData FormServicegetTaskFormData(String taskId)
1
1
外部表单
根据表单文件自行渲染的任务表单,称为外部表单。
<process id="leave" name="请假流程-内置表单">
<startEvent id="start" flowable:formKey="form1"></startEvent>
</process>
1
2
3
4
1
2
3
4
外部表单的定义
表单定义文件的后缀为form。
表单的JSON定义以key、name和description开头。
表单引擎通过属性key来辨别表单在整个表单引擎中的唯一身份。对于来源相同的同一个表单定义的版本系统也是基于属性key运作的。
第二部分是一个数组类型fields,表单定义的字段在这里阐明。
第三部分是可选的,用来定义表单的结果outcomes。
xml文件例子
{
"key": "form1",
"name": "My first form",
"fields": [
{
"id": "input1",
"name": "Input1",
"type": "text",
"required": false,
"placeholder": "empty"
}
],
"outcomes": [
{
"id": "null",
"name": "Accept"
},
{
"id": "null",
"name": "Reject"
}
]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
部署表单
在springboot环境下,resources/forms目录下任何form后缀的表单定义文件都会被自动部署。
实际应用中,应当让前端流程设计器生成指定格式的表单定义文件,通过与前文提到的接口方式,更新部署流程定义及表单定义资源。
获取及提交表单参数
实际上,渲染表单所需的所有数据都组装在下面两个方法:
StartFormData FormServicegetStartFormData(String processDefinitionId)
TaskFormdata FormServicegetTaskFormData(String taskId)
1
2
3
1
2
3
ProcessInstance FormServicesubmitStartFormData(String processDefinitionId, Map<String,String> properties)
void FormServicesubmitTaskFormData(String taskId, Map<String,String> properties)


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

原文地址: http://outofmemory.cn/yw/13365590.html

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

发表评论

登录后才能评论

评论列表(0条)

保存