https://github.com/xuexiangjys/xtask
一个拓展性极强的Android任务执行框架。可自由定义和组合任务来实现你想要的功能,尤其适用于处理复杂的业务流程,可灵活添加前置任务或者调整执行顺序。例如:应用的启动初始化流程。
https://github.com/xuexiangjys/xtask
android task-manager task-runner x-library
Last synced: 6 months ago
JSON representation
一个拓展性极强的Android任务执行框架。可自由定义和组合任务来实现你想要的功能,尤其适用于处理复杂的业务流程,可灵活添加前置任务或者调整执行顺序。例如:应用的启动初始化流程。
- Host: GitHub
- URL: https://github.com/xuexiangjys/xtask
- Owner: xuexiangjys
- License: apache-2.0
- Created: 2021-10-09T18:35:22.000Z (about 4 years ago)
- Default Branch: master
- Last Pushed: 2024-03-12T15:03:52.000Z (over 1 year ago)
- Last Synced: 2024-03-12T16:29:56.926Z (over 1 year ago)
- Topics: android, task-manager, task-runner, x-library
- Language: Java
- Homepage: https://github.com/xuexiangjys/XTask/wiki
- Size: 1.14 MB
- Stars: 139
- Watchers: 4
- Forks: 26
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# XTask
[](https://jitpack.io/#xuexiangjys/XTask)
[](https://android-arsenal.com/api?level=14)
[](https://github.com/xuexiangjys/XTask/issues)
[](https://github.com/xuexiangjys/XTask)一个拓展性极强的Android任务执行框架。可自由定义和组合任务来实现你想要的功能,尤其适用于处理复杂的业务流程,可灵活添加前置任务或者调整执行顺序。例如:应用的启动初始化流程。
在使用前,请一定要仔细阅读[使用说明文档](https://github.com/xuexiangjys/XTask/wiki),重要的事情说三遍!!!
在使用前,请一定要仔细阅读[使用说明文档](https://github.com/xuexiangjys/XTask/wiki),重要的事情说三遍!!!
在使用前,请一定要仔细阅读[使用说明文档](https://github.com/xuexiangjys/XTask/wiki),重要的事情说三遍!!!
## 关于我
| 公众号 | 掘金 | 知乎 | CSDN | 简书 | 思否 | 哔哩哔哩 | 今日头条
|---------|---------|--------- |---------|---------|---------|---------|---------|
| [我的Android开源之旅](https://t.1yb.co/Irse) | [点我](https://juejin.im/user/598feef55188257d592e56ed/posts) | [点我](https://www.zhihu.com/people/xuexiangjys/posts) | [点我](https://xuexiangjys.blog.csdn.net/) | [点我](https://www.jianshu.com/u/6bf605575337) | [点我](https://segmentfault.com/u/xuexiangjys) | [点我](https://space.bilibili.com/483850585) | [点我](https://img.rruu.net/image/5ff34ff7b02dd)## X系列库快速集成
为了方便大家快速集成X系列框架库,我提供了一个空壳模版供大家参考使用: https://github.com/xuexiangjys/TemplateAppProject
除此之外,我还特别制作了几期[X系列视频教程](https://space.bilibili.com/483850585/channel/detail?cid=104998)供大家学习参考.
---
## 特征
* 支持6种线程类型方式执行任务。
* 支持任务链中各任务的执行线程调度和控制。
* 支持快捷任务创建,同时支持自定义任务。
* 支持串行和并行等组任务。
* 支持任务间数据共享。
* 支持自由组合任务执行。
* 支持任务链执行取消。
* 支持取消所有任务链和指定名称的任务链。
* 支持任务链调用顺序记录和查询。
* 支持自定义任务执行的线程池。## 组成结构
* 任务链`ITaskChainEngine`:任务链执行引擎,负责统筹调度各任务步骤。
* 任务步骤`ITaskStep`:负责具体任务逻辑处理。
* 数据存储仓库`IDataStore`:存放数据的仓库,主要用于保存任务参数中的数据。
* 任务参数`ITaskParam`:负责任务路径记录以及任务产生的参数管理。
* 任务执行结果`ITaskResult`:存放任务最终执行的结果以及产生的数据。
* 任务组`IGroupTaskStep`:负责统筹调度各子任务步骤。
[点击查看框架UML设计图](https://github.com/xuexiangjys/XTask/blob/master/art/xtask_uml.png)
## 日志一览


---
## 集成指南
### 添加Gradle依赖
1.先在项目根目录的 `build.gradle` 的 `repositories` 添加:
```
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
```2.然后在应用项目(一般是app)的 `build.gradle` 的 dependencies 添加:
```
dependencies {
...
// XTask
implementation 'com.github.xuexiangjys.XTask:xtask-core:1.0.2'
}
```## 使用方法
> [XTask](https://github.com/xuexiangjys/XTask/blob/master/xtask-core/src/main/java/com/xuexiang/xtask/XTask.java)作为对外统一的API入口,所有常用的方法都能从中找到。
### 打开调试模式
当需要定位问题,需要进行调试时,可打开调试模式,这样便可开启框架的日志。
```
XTask.debug(true);
```### XTask的API介绍
方法名 | 描述
|---|---
debug | 设置是否打开调试
setLogger | 自定义日志打印
setIsLogThreadName | 设置是否打印任务执行所在的线程名,默认false
getTaskChain | 获取任务链执行引擎
getTask | 获取简化的任务
getTaskBuilder | 获取简化任务的构建者
getConcurrentGroupTask | 获取并行任务组
getSerialGroupTask | 获取串行任务组
cancelTaskChain | 取消指定任务链执行
cancelAllTaskChain | 取消所有任务链执行
postToMain | 执行任务到主线程
postToMainDelay | 延迟执行任务到主线程
submit | 执行普通异步任务
emergentSubmit | 执行紧急异步任务
backgroundSubmit | 执行后台异步任务
ioSubmit | 执行io耗时的异步任务
groupSubmit | 执行分组异步任务
schedule | 执行延期任务
scheduleAtFixedRate | 执行周期任务(固定间期)
scheduleWithFixedDelay | 执行周期任务(固定延期)### 如何执行一条任务链
下面是一整个完整的例子:
```
// 1.创建一条任务链(必须)
final TaskChainEngine engine = XTask.getTaskChain();
// 2.设置任务链的初始化参数(可选)
engine.setTaskParam(TaskParam.get("chainName", engine.getName()));
TaskParam taskParam = TaskParam.get("param1", 100)
.put("param2", true);
// 3.创建多个任务,并向任务链中添加(必须)
XTaskStep taskStep = XTask.getTask(new TaskCommand() {
@Override
public void run() {
ITaskParam param = getTaskParam();
Log.e(TAG, getName() + " start, param1:" + param.get("param1") + ", chainName:" + param.get("chainName"));
param.put("param1", 200);
param.put("param3", "this is param3!");
}
}, taskParam);
engine.addTask(taskStep)
.addTask(XTask.getTask(new TaskCommand() {
@Override
public void run() {
ITaskParam param = getTaskParam();
Log.e(TAG, getName() + " start, param1:" + param.get("param1") + ", param3:" + param.get("param3"));
param.put("param2", false);
}
}));
// 4.设置任务链执行回调(可选)
ICanceller canceller = engine.setTaskChainCallback(new TaskChainCallbackAdapter() {
@Override
public void onTaskChainCompleted(@NonNull ITaskChainEngine engine, @NonNull ITaskResult result) {
Log.e(TAG, "task chain completed, thread:" + Thread.currentThread().getName());
Map data = result.getDataStore().getData();
for (Map.Entry entry : data.entrySet()) {
Log.e(TAG, "key:" + entry.getKey() + ", value:" + entry.getValue());
}
}
// 5.任务链执行(必须)
}).start();
```1.创建一条任务链.(必须)
```
TaskChainEngine engine = XTask.getTaskChain();
```2.设置任务链的初始化参数.(可选)
```
engine.setTaskParam(TaskParam.get("chainName", engine.getName()));
```3.创建多个任务,并向任务链中添加.(必须)
```
// 设置任务初始化参数
TaskParam taskParam = TaskParam.get("param1", 100)
.put("param2", true);
XTaskStep taskStep = XTask.getTask(new TaskCommand() {
@Override
public void run() {
// ...执行任务
}
}, taskParam);
engine.addTask(taskStep)
.addTask(XTask.getTask(new TaskCommand() {
@Override
public void run() {
// ...执行任务
}
}));
```【注意】对于任务执行完成,需要注意以下两点:
* 如果任务执行成功,就调用`notifyTaskSucceed`,任务执行失败,就调用`notifyTaskFailed`。这里任务无论成功还是失败,只要执行完成都需要调用`notifyTaskXXX`通知任务链该任务完成,否则任务将无法正常执行。
* `TaskCommand`和`SimpleTaskStep`默认提供了自动通知执行结果的功能,但是AbstractTaskStep没有提供,需要手动通知。4.设置任务链执行回调.(可选)
调用setTaskChainCallback设置任务链执行回调。
```
engine.setTaskChainCallback(new TaskChainCallbackAdapter() {@Override
public boolean isCallBackOnMainThread() {
// 回调是否返回主线程, 默认是true
return false;
}
@Override
public void onTaskChainStart(@NonNull ITaskChainEngine engine) {
Log.e(TAG, "task chain start");
}
@Override
public void onTaskChainCompleted(@NonNull ITaskChainEngine engine, @NonNull ITaskResult result) {
Log.e(TAG, "task chain completed, thread:" + Thread.currentThread().getName());
}
@Override
public void onTaskChainError(@NonNull ITaskChainEngine engine, @NonNull ITaskResult result) {
Log.e(TAG, "task chain error");
}
})
```5.任务链执行.(必须)
调用start执行任务链。
```
ICanceller canceller = engine.start();
```## 任务创建
创建任务有两种方式:
* 通过XTask.getTask构建
* 继承`SimpleTaskStep`/`AbstractTaskStep`实现任务的自定义### 通过XTask创建
> 通过XTask.getTask, 传入对应的属性进行构建
属性名 | 描述 | 默认值
|---|---|---
name | 任务步骤名称 | XTaskStep-N(N为自增数)
command | 任务执行内容 | /
threadType | 线程执行类型 | ThreadType.ASYNC
taskParam | 任务参数 | new TaskParam()
taskHandler | 任务处理者 | null
isAutoNotify | 是否自动通知任务执行结果 | true
```
XTaskStep taskStep = XTask.getTask(new TaskCommand() {
@Override
public void run() {
// todo
}
}, ThreadType.ASYNC, taskParam);
```### 通过继承创建
> 通过继承`SimpleTaskStep`或者`AbstractTaskStep`实现具体功能。
```
public class StepATask extends SimpleTaskStep {@Override
public void doTask() throws Exception {
// todo
// 不需要手动通知任务链任务完成
}
}public class StepBTask extends AbstractTaskStep {
@Override
public void doTask() throws Exception {
// todo
// 需手动通知任务链任务完成
notifyTaskSucceed(TaskResult.succeed());
}@Override
public String getName() {
return "StepATask";
}
}
```## 任务执行原则
每一个任务都是依托于任务链进行流程控制。任何任务都需要遵循以下原则:
* 任何任务无论失败还是成功,都需要调用`notifyTaskSucceed`或者`notifyTaskFailed`去通知任务链任务的完成情况。`TaskCommand`和`SimpleTaskStep`默认提供了自动通知执行结果的功能。
* 一旦任务链中某个任务执行失败,整个链路都停止工作。任务类型 | 任务执行说明
|---|---
TaskCommand | 自动通知执行结果。如需手动通知,只需设置`isAutoNotify`为false即可
SimpleTaskStep | 自动通知执行结果。如需手动通知,只需重写`isAutoNotify`方法为false即可
AbstractTaskStep | 需手动通知执行结果### TaskCommand手动通知执行结果
在通过XTask.getTask传入TaskCommand构建Task的时候,设置`isAutoNotify`为false即可手动通知执行结果。
```
final TaskChainEngine engine = XTask.getTaskChain();
for (int i = 0; i < 5; i++) {
int finalI = i;
engine.addTask(XTask.getTask(new TaskCommand() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (finalI == 2) {
notifyTaskFailed(404, "任务执行失败!");
} else {
notifyTaskSucceed(TaskResult.succeed());
}
}
}, false)); // 设置手动通知执行结果
}
engine.start();
```### SimpleTaskStep手动通知执行结果
重写`SimpleTaskStep`的`isAutoNotify`方法为false即可手动通知执行结果。
```
public class StepATask extends SimpleTaskStep {@Override
public void doTask() throws Exception {
// todo
// 手动通知任务链任务完成
notifyTaskSucceed();
}@Override
protected boolean isAutoNotify() {
return false;
}
}
```## 参数传递
* 任何TaskStep我们都可以通过`getTaskParam`获取任务参数和任务执行结果`ITaskParam`。
* 上一个TaskStep保存处理过的任务参数会自动带入到下一个TaskStep中去,因此最后一个TaskStep拥有之前所有任务的参数数据。```
XTask.getTask(new TaskCommand() {
@Override
public void run() {
ITaskParam param = getTaskParam();
Log.e(TAG, getName() + " start, param1:" + param.get("param1") + ", param3:" + param.get("param3"));
param.put("param2", false);
}
})
```## 线程控制
设置任务的threadType类型,即可完成对任务运行线程的控制。目前支持6种线程处理方式。
类型 | 描述 | 线程池构成
|---|---|---
MAIN | 主线程(UI线程) | /
ASYNC | 异步线程(开子线程,普通线程池) | 核心线程数和最大线程为CPU数,0s keepTime,LinkedBlockingQueue(128),线程优先级5
ASYNC_IO | 异步线程(开子线程,io线程池) | 核心线程数和最大线程为(2*CPU数+1),30s keepTime,LinkedBlockingQueue(128),线程优先级5
ASYNC_EMERGENT | 异步线程(开子线程,紧急线程池) | 核心线程数为2,最大线程为∞,60s keepTime,SynchronousQueue(不阻塞),线程优先级10
ASYNC_BACKGROUND | 异步线程(开子线程,优先级较低线程池) | 核心线程数和最大线程为2,0s keepTime,LinkedBlockingQueue(128),线程优先级1
SYNC | 同步线程(直接执行) | /```
// 1.构造时传入线程
XTaskStep taskStep = XTask.getTask(new SimpleTaskCommand(1000), ThreadType.ASYNC_EMERGENT);
// 2.设置线程的方法
taskStep.setThreadType(ThreadType.ASYNC_IO);
```## 任务组
目前共有串行任务组(SerialGroupTaskStep)和并行任务组(ConcurrentGroupTaskStep)
### 串行任务组
串行任务组是按顺序依次执行,和任务链的处理方式类似。使用XTask.getSerialGroupTask获取。
```
final TaskChainEngine engine = XTask.getTaskChain();
SerialGroupTaskStep group1 = XTask.getSerialGroupTask("group1");
for (int i = 0; i < 5; i++) {
group1.addTask(XTask.getTask(new SimpleTaskCommand(500)));
}
SerialGroupTaskStep group2 = XTask.getSerialGroupTask("group2");
for (int i = 0; i < 5; i++) {
group2.addTask(XTask.getTask(new SimpleTaskCommand(1000)));
}
ICanceller canceller = engine.addTask(group1)
.addTask(group2)
.setTaskChainCallback(new TaskChainCallbackAdapter() {
@Override
public void onTaskChainCompleted(@NonNull ITaskChainEngine engine, @NonNull ITaskResult result) {
Log.e(TAG, "task chain completed, path:" + result.getPath());
}
})
.start();
addCanceller(canceller);
```### 并行任务组
并行任务组是组内所有任务同时执行,待所有任务都完成后才视为任务组完成。使用XTask.getConcurrentGroupTask获取。
```
final TaskChainEngine engine = XTask.getTaskChain();
ConcurrentGroupTaskStep group1 = XTask.getConcurrentGroupTask("group1");
for (int i = 0; i < 5; i++) {
group1.addTask(XTask.getTask(new SimpleTaskCommand(100 * (i + 1))));
}
ConcurrentGroupTaskStep group2 = XTask.getConcurrentGroupTask("group2");
for (int i = 0; i < 5; i++) {
group2.addTask(XTask.getTask(new SimpleTaskCommand(200 * (i + 1))));
}
ICanceller canceller = engine.addTask(group1)
.addTask(group2)
.setTaskChainCallback(new TaskChainCallbackAdapter() {
@Override
public void onTaskChainCompleted(@NonNull ITaskChainEngine engine, @NonNull ITaskResult result) {
Log.e(TAG, "task chain completed, path:" + result.getPath());
}
})
.start();
addCanceller(canceller);
```## 任务链取消
> 通过调用`ICanceller`的`cancel`方法或者`XTask`的`cancelTaskChain`即可完成任务链的取消。
### 单个任务链取消
调用任务链`TaskChainEngine`的`start`方法之后,会返回一个任务取消者`ICanceller`,调用它的`cancel`方法即可完成任务取消。
```
ICanceller canceller = engine.start();
// 取消任务链的执行
canceller.cancel();
```### 多个任务链取消
任务链在执行的时候,会默认加入到一个任务取消池,调用`XTask`的`cancelTaskChain`方法,传入多个任务链的名称或者`ICanceller`的名称,即可完成多个任务链的取消。
```
Set pool = new HashSet<>();
ICanceller canceller1 = engine1.start();
ICanceller canceller2 = engine2.start();
// 使用ICanceller的名称
pool.add(canceller1.getName());
// 使用任务链的名称
pool.add(engine2.getName());
// 取消多个任务链的执行
XTask.cancelTaskChain(pool);
```### 全部任务链取消
调用`XTask`的`cancelAllTaskChain`方法取消全部任务链的执行
```
XTask.cancelAllTaskChain();
```---
## 如果觉得项目还不错,可以考虑打赏一波
> 你的打赏是我维护的动力,我将会列出所有打赏人员的清单在下方作为凭证,打赏前请留下打赏项目的备注!

## 联系方式
> 更多资讯内容,欢迎扫描关注我的个人微信公众号:【我的Android开源之旅】
