Activity-错误事件

本文介绍了一个基于BPMN的流程设计案例,该流程包括了销售线索的审核及异常处理机制。当利润评估环节出现问题时,流程将通过错误事件触发额外信息补充,并能重新进入审核流程。

设计一个流程:

提交一个新的 sales leader, 创建一个子流程, 在子流程中同时对 customer rating 以及 profitability 进行考察, 如果同时通过, 则结束子流程, 完成主流程的 Store lead in CRM system 任务以及结束节点

如果 profitability 任务没有提供足够的信息, 则会抛出错误事件, 错误事件被边界事件所捕获, 进入 Provide additional details 流程, 并重新进入开始子流程

xml文件

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
  xmlns:activiti="http://activiti.org/bpmn" targetNamespace="Examples"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL
             http://www.omg.org/spec/BPMN/2.0/20100501/BPMN20.xsd">

  <error id="notEnoughInfoError" errorCode="not_enough_info" />
  <process id="reviewSaledLead" name="Review sales lead">
    <startEvent id="theStart" activiti:initiator="initiator" />
    <sequenceFlow id="flow1" sourceRef="theStart" targetRef="provideNewSalesLead"/>
    <userTask id="provideNewSalesLead" name="Provide new sales lead" activiti:assignee="${initiator}">
      <extensionElements>
        <activiti:formProperty id="customerName" name="Customer name" type="string" required="true"/>
        <activiti:formProperty id="potentialProfit" name="Potential profit" type="long" />
        <activiti:formProperty id="details" name="Details" type="string"/>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow2" sourceRef="provideNewSalesLead" targetRef="reviewSalesLeadSubProcess"/>
    <!-- 子流程 -->
    <subProcess id="reviewSalesLeadSubProcess" name="Review sales lead">
      <startEvent id="subProcessStart" />
      <sequenceFlow id="flow3" sourceRef="subProcessStart" targetRef="fork"/>
      <sequenceFlow id="flow4" sourceRef="fork" targetRef="reviewProfitability"/>
      <parallelGateway id="fork" />
      <sequenceFlow id="flow5" sourceRef="fork" targetRef="reviewCustomerRating"/>
      <userTask id="reviewCustomerRating" name="Review customer rating" activiti:candidateGroups="accountancy" />
      <sequenceFlow id="flow6" sourceRef="reviewCustomerRating" targetRef="subProcessEnd1"/>
      <endEvent id="subProcessEnd1" />
      <userTask id="reviewProfitability" name="Review profitability" activiti:candidateGroups="management">
        <documentation>
          ${initiator} has published a new sales lead: ${customerName}. Details: ${details}
        </documentation>
        <extensionElements>
          <activiti:formProperty id="notEnoughInformation" name="Do you believe this customer is profitable?" type="enum" required="true">
            <activiti:value id="false" name="Yes" />
            <activiti:value id="true" name="No (= request more info)" />
          </activiti:formProperty>
        </extensionElements>
      </userTask>
      <sequenceFlow id="flow7" sourceRef="reviewProfitability" targetRef="enoughInformationCheck"/>
      <exclusiveGateway id="enoughInformationCheck" name="Enough information?" />
      <sequenceFlow id="flow8" sourceRef="enoughInformationCheck" targetRef="notEnoughInformationEnd">
        <conditionExpression>${notEnoughInformation == 'true'}</conditionExpression>
      </sequenceFlow>
      <sequenceFlow id="flow9" sourceRef="enoughInformationCheck" targetRef="subProcessEnd2">
        <conditionExpression>${notEnoughInformation == 'false'}</conditionExpression>
      </sequenceFlow>
      <endEvent id="subProcessEnd2" />
      <endEvent id="notEnoughInformationEnd">
        <errorEventDefinition errorRef="notEnoughInfoError" />
      </endEvent>
    </subProcess>
    <sequenceFlow id="flow10" sourceRef="reviewSalesLeadSubProcess" targetRef="storeLeadInCrmSystem"/>
    <boundaryEvent attachedToRef="reviewSalesLeadSubProcess" cancelActivity="true" id="catchNotEnoughInformationError" >
      <errorEventDefinition errorRef="notEnoughInfoError" />
    </boundaryEvent>
    <sequenceFlow id="flow11" sourceRef="catchNotEnoughInformationError" targetRef="provideAdditionalDetails"/>
    <userTask id="provideAdditionalDetails" name="Provide additional details" activiti:assignee="${initiator}">
      <documentation>Provide additional details for ${customerName}.</documentation>
      <extensionElements>
        <activiti:formProperty id="details" name="Additional details" type="string" required="true"/>
      </extensionElements>
    </userTask>
    <sequenceFlow id="flow12" sourceRef="provideAdditionalDetails" targetRef="reviewSalesLeadSubProcess"/>
    <task id="storeLeadInCrmSystem" name="Store lead in CRM system" />
    <sequenceFlow id="flow13" sourceRef="storeLeadInCrmSystem" targetRef="processEnd"/>
    <endEvent id="processEnd" />
  </process>

</definitions>

代码:

package com.lala.boundaryerrorevent;

import common.ProcessEngineUtil;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;

public class BoundaryErrorEvent {
    public static void main(String[] args) {
        // 设置流程发起者
        Authentication.setAuthenticatedUserId("destiny");
        ProcessEngineUtil processEngineUtil = new ProcessEngineUtil("boundaryErrorEvent.bpmn20.xml");
        ProcessEngine processEngine = processEngineUtil.getProcessEngine();
        Map<String, Object> variables = new HashMap<>();
        variables.put("details", "interesting");
        variables.put("customerName", "Camery");
        ProcessInstance processInstance = processEngine.getRuntimeService().
            startProcessInstanceByKey("reviewSaledLead", variables);
        TaskService taskService = processEngine.getTaskService();

        // 流程启动,列出当前由destiny的创建所有流程,当前是在开始的第一个节点Provide new sales lead
        System.out.println("流程开始");
        Task task = taskService.createTaskQuery()
            .taskAssignee("destiny")
            .singleResult();
        System.out.println("task name: " + task.getName());
        // 提交节点
        taskService.complete(task.getId());

        // 进入并行网关, 会同时生成两个 task, 一个到eview customer rating,另外一个到Review profitability
        Task ratingTask = taskService.createTaskQuery().taskCandidateGroup("accountancy").singleResult();
        System.out.println("ratingTask name: " + ratingTask.getName());

        Task profitabilityTask = taskService.createTaskQuery().taskCandidateGroup("management").singleResult();
        System.out.println("profitabilityTask name: " + profitabilityTask.getName());

        // Review profitability 提交后就会触发 errorEvent
        variables = new HashMap<>();
        variables.put("notEnoughInformation", true);
        taskService.complete(profitabilityTask.getId(), variables);

        // 查找流程发起者 destiny 对应的 task
        // 此时 errorEvent 会被边界条件捕获, 整个事件会流转到 Provide additional details
        Task provideDetailsTask = taskService.createTaskQuery().taskAssignee("destiny").singleResult();
        System.out.println("provideDetailsTask: {}" + provideDetailsTask);
        System.out.println("provideDetailsTask name: " + provideDetailsTask.getName());


        // 完成 Provide additional details 节点后, 会重新进入子流程
        taskService.complete(provideDetailsTask.getId());
        List<Task> reviewTasks = taskService.createTaskQuery().orderByTaskName().asc().list();
        for (Task reviewTask : reviewTasks) {
            System.out.println("reviewTask name: " + reviewTask.getName());
        }
        // 完成子流程的两个节点
        taskService.complete(reviewTasks.get(0).getId());
        variables.put("notEnoughInformation", false);
        taskService.complete(reviewTasks.get(1).getId(), variables);
        // 画出整套流程图
        processEngineUtil.draw(processInstance);
    }
}

流程图:

 

<think>我们正在讨论adb shell am start命令,特别是带有各种参数(如--activity-clear-task)的情况。用户希望了解这些参数的含义、作用以及可能出现的问题和解决办法。 根据提供的引用,我们知道adb shell am start的基本用法是启动一个Activity。引用[1]、[2]、[3]都展示了启动Activity的命令格式,其中引用[3]还展示了一个带有额外参数(-a和-c)的例子。引用[4]则显示了一个启动日志,其中包含了一些错误信息。 现在,用户特别询问了使用`--activity-clear-task`等众多参数的情况。虽然引用中没有直接提到`--activity-clear-task`,但我们可以根据Android开发知识来回答。 首先,回顾adb shell am start的基本语法: ``` adb shell am start [options] <INTENT> ``` 其中,INTENT用于指定要启动的组件(如Activity)以及相关数据。常见的指定组件的方式是使用`-n`参数(如`-n com.larus.nova/.MainActivity`)。 至于参数`--activity-clear-task`,它是启动Activity时可以使用的标志(flag)之一。这些标志用于控制Activity的启动行为。在Android中,这些标志通常对应于Intent的标志(如Intent.FLAG_ACTIVITY_CLEAR_TASK)。 以下是常见的一些参数及其含义: 1. `--activity-clear-task`:这个标志会清除与要启动的Activity相关的任务栈(task)。也就是说,如果这个Activity已经在一个任务栈中存在,那么在这个Activity启动之前,任务栈中所有的其他Activity都会被清除。这样,新启动的Activity就会成为这个任务栈中唯一的Activity。这个标志通常与`--activity-new-task`一起使用。 2. `--activity-new-task`:等同于Intent.FLAG_ACTIVITY_NEW_TASK。它会将Activity启动到一个新的任务栈中。如果已经有这个Activity的任务栈存在,则会把该任务栈调到前台,而不创建新的实例(除非同时设置了其他标志)。 3. `--activity-clear-top`:如果当前任务栈中已经存在该Activity的实例,并且它不在栈顶,那么位于它上面的所有Activity都会被销毁,从而让它成为栈顶的Activity。 4. `--activity-single-top`:如果要启动的Activity正好位于任务栈的顶部,则不会创建新的实例,而是调用该Activity的onNewIntent()方法。如果不在栈顶,则创建新实例。 5. `--activity-no-history`:Activity启动后,当用户离开它时,它不会保留在任务栈中。 6. `--activity-multiple-task`:允许创建多个任务栈(通常与`--activity-new-task`一起使用)。 7. `--activity-exclude-from-recents`:使得Activity启动的任务栈不会出现在最近任务列表中。 8. `--activity-reorder-to-front`:如果该Activity已经在任务栈中,则将它移动到栈顶,而不创建新实例。 除了上述参数,还可以使用`-a`指定action,`-c`指定category,`-d`指定data,`-t`指定MIME类型等。 可能出现的问题及解决方法: 1. 问题:参数使用错误导致无法启动Activity。 解决方法:检查参数是否正确,特别是标志的组合是否合理。例如,`--activity-clear-task`通常需要和`--activity-new-task`一起使用,否则可能无效。 2. 问题:启动Activity后,应用行为不符合预期(如任务栈被清空,或者多个实例被创建)。 解决方法:检查启动标志的设置是否合理。例如,如果不想每次启动都创建新的实例,可以考虑使用`--activity-single-top`;如果想清空整个任务栈,则使用`--activity-clear-task`。 3. 问题:在日志中出现错误,如引用[4]中的“startActivity called from finishing ActivityRecord”警告。 解决方法:这个警告表示从一个正在结束的Activity启动新Activity,系统强制添加了FLAG_ACTIVITY_NEW_TASK。如果这不是你期望的行为,可以检查启动时机,确保不要在Activity销毁过程中启动新Activity。 4. 问题:权限不足导致启动失败。 解决方法:确保要启动的Activity是导出的(exported=true),或者应用拥有相应的权限。 5. 问题:启动命令中包名或Activity类名写错。 解决方法:使用正确的包名和Activity类名。可以通过`adb shell dumpsys package`来查看应用的信息。 举例说明,如果要启动`com.larus.nova/.MainActivity`并清空任务栈,可以这样写: ``` adb shell am start -n com.larus.nova/.MainActivity --activity-clear-task --activity-new-task ``` 注意:在命令行中,多个参数之间用空格隔开。 总结:adb shell am start命令的参数主要用于控制Activity的启动模式和行为,合理使用这些参数可以满足不同的启动需求。在遇到问题时,需要结合日志具体分析。 </think>以下是关于 `adb shell am start` 命令中 `--activity-clear-task` 等参数的含义、作用及可能出现问题的详细解答: --- ### **参数含义与作用** #### 1. `--activity-clear-task` - **功能**:清除任务栈中所有现有 Activity,使目标 Activity 成为新任务栈的根节点。 - **使用场景**: 当需要完全重置应用状态时(如冷启动),确保目标 Activity 是唯一入口点。 示例: ```bash adb shell am start -n com.larus.nova/.MainActivity --activity-clear-task ``` #### 2. **其他常用参数** | 参数 | 功能 | 示例 | |------|------|------| | `--activity-new-task` | 在新任务栈中启动 Activity | `--activity-new-task` | | `--activity-single-top` | 若目标 Activity 已在栈顶,则不创建新实例 | `--activity-single-top` | | `--activity-clear-top` | 清除目标 Activity 之上的所有 Activity | `--activity-clear-top` | | `-a <ACTION>` | 指定 Intent Action(如 `android.intent.action.VIEW`) | `-a android.intent.action.VIEW` | | `-c <CATEGORY>` | 指定 Intent Category(如 `android.intent.category.LAUNCHER`) | `-c android.intent.category.LAUNCHER` | | `-d <DATA_URI>` | 传递数据 URI(如打开链接) | `-d https://example.com` | | `--ei <EXTRA_INT>` | 附加整型数据到 Intent | `--ei key_name 123` | --- ### **常见问题与解决方法** #### 1. **参数冲突导致启动失败** - **问题**: 组合使用互斥参数(如 `--activity-clear-task` + `--activity-single-top`)可能崩溃。 - **解决**: 避免冲突组合,优先使用标准启动模式(如仅用 `--activity-clear-task` 重置任务栈)。 #### 2. **Activity 未导出或权限不足** - **问题**: 错误日志:`Permission Denial` 或 `Activity not found`(如引用[4]中的权限错误)。 - **解决**: - 确认 `AndroidManifest.xml` 中目标 Activity 已设置 `android:exported="true"`。 - 检查系统级权限(如 `START_TASKS_FROM_RECENTS`)。 #### 3. **包名或 Activity 路径错误** - **问题**: 错误日志:`Unable to find explicit activity class`(如引用[3]中的路径错误)。 - **解决**: - 验证包名:`adb shell pm list packages | grep nova`。 - 确认完整 Activity 路径:`adb shell dumpsys package com.larus.nova | grep MainActivity`。 #### 4. **任务栈状态冲突** - **问题**: 从正在销毁的 Activity 启动新任务栈(如引用[4]中的 `startActivity called from finishing ActivityRecord`)。 - **解决**: 添加延时或确保前一个 Activity 已完全销毁: ```bash adb shell am force-stop com.larus.nova # 先强制停止应用 adb shell am start ... # 再启动目标 Activity ``` --- ### **完整命令示例** ```bash # 清空任务栈并启动 MainActivity adb shell am start -n com.larus.nova/.MainActivity \ --activity-clear-task \ # 清空栈 --activity-new-task \ # 新任务栈 -a android.intent.action.MAIN \ # 主入口 -c android.intent.category.LAUNCHER # Launcher 类别 ``` --- ### **关键注意事项** 1. **参数顺序**: 参数需放在 `-n` 或 `-a` 等主指令**之后**(如 `am start -n package/activity --param`)。 2. **日志分析**: 使用 `adb logcat | grep ActivityManager` 查看详细启动错误。 3. **权限限制**: 部分参数(如 `--activity-clear-task`)需系统级权限,普通应用可能无法使用。 [^1] [^2] [^3] [^4] [^5] ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值