# RxTask **Repository Path**: yywds/RxTask ## Basic Information - **Project Name**: RxTask - **Description**: 数据同步异步 - **Primary Language**: Android - **License**: Not specified - **Default Branch**: dev - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2021-02-24 - **Last Updated**: 2023-01-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README RxTask,基于线程池+handler封装工具。从此告别到处创建handler,远离到处创建线程无法管理。
已迁移到Androidx

早期的版本介绍:
[RxTask初版上篇](https://juejin.im/post/5b587651f265da0f783ca731)
[RxTask初版下篇](https://juejin.im/post/5b5f01416fb9a04fae211bb1)
[项目地址](https://gitee.com/biyouji/RxTask) [我的Github](https://github.com/AcgnCodeMonkey) [我的码云](https://gitee.com/biyouji_admin_admin) **集成方式: implementation 'com.xujl:task:1.0.1'**
### 初始化 ~~~java //默认初始化,默认初始化后核心线程数为cpu核心数X4 RxExecutor.getInstance().init(); //自定义核心线程数量进行初始化 RxExecutor.getInstance().init(32); //完全自定义工具线程池 RxExecutor.getInstance().init(ExecutorService); //关闭log输出,默认为开启 RxExecutor.getInstance().setDebug(false); ~~~ ### 如何使用? #### 场景1 ##### 子线程任务,执行完毕结果数据返回给主线程显示
~~~java RxExecutor.getInstance() .executeTask(new Task(){ @Override public void run (Emitter emitter) throws Exception { super.run(emitter); //当前为子线程 //模拟子线程任务 Thread.sleep(1000); //任务结束发送数据到主线程 emitter.next("任务执行结果数据"); } @Override public void onNext (String data) { super.onNext(data); //当前为主线程 //显示子线程执行结果 textView.setText(data); } }); ~~~ #### 场景2 ##### 子线程任务,不关心任务结果,只关心完成时机
~~~java RxExecutor.getInstance() .executeTask(new Task() { @Override public void run (Emitter emitter) throws Exception { super.run(emitter); //当前为子线程 //模拟子线程任务 Thread.sleep(1000); //任务结束 } @Override public void onFinished () { super.onFinished(); //当前为主线程 // 执行主线程逻辑 } }); ~~~ #### 场景3 ##### 单纯执行一个子线程任务,不关心任务结果,也不需要在任务结束后有任何操作
~~~java RxExecutor.getInstance() .executeTask(new Task() { @Override public void run (Emitter emitter) throws Exception { super.run(emitter); //当前为子线程 //模拟子线程任务 Thread.sleep(1000); //任务结束 } }); ~~~ #### 场景4 ##### 执行一个普通子线程而非task
~~~java RxExecutor.getInstance() .executeRunnableTask(new Runnable() { @Override public void run () { //当前为子线程 //模拟子线程任务 Thread.sleep(1000); //任务结束 } }); ~~~ #### 场景5 ##### 执行的任务绑定生命周期,界面销毁后,不再回调
在bindLife方法中完成绑定,生命周期结束后,onFinished和onNext将不会再回调。 ~~~java private RxLifeList mBindLife = new RxLifeList(); private void test(){ RxExecutor.getInstance() .executeTask(new Task() { @Override public void run (Emitter emitter) throws Exception { super.run(emitter); //当前为子线程 //模拟子线程任务 Thread.sleep(2000); //任务结束 } @Override public void onNext (String data) { super.onNext(data); } @Override public void onFinished () { super.onFinished(); //当前为主线程 // 执行主线程逻辑 } @Override public void bindLife (RxLife rxLife) { super.bindLife(rxLife); mBindLife.add(rxLife); } }); } @Override protected void onDestroy () { if (mBindLife != null) { mBindLife.onDestroy(); } super.onDestroy(); } ~~~ #### 场景6 ##### 当前处于某个子线程任务中,需要主线程中显示数据
~~~java //其他子线程中 new Thread(new Runnable() { @Override public void run () { //模拟子线程任务 Thread.sleep(1000); //切换回主线程进行逻辑 RxExecutor.getInstance() .executeUiTask(new Task() { @Override public void onlyRunUiTask () { super.onlyRunUiTask(); //执行主线程逻辑 } }); } }).start(); ~~~ #### 场景7 ##### 任务执行失败,进行重试
使用 TaskBuilder.create().setRetryMaxCount(3)传入task构造器即可实现重试功能,方法参数为最大重试次数,传入 TaskRetry.INFINITE可实现无限重试(**通常不建议这么做!**)。
**Task默认配置为失败后不重试**
任务失败后会回调onError方法并返回具体错误,如果没有配置重试,进入onError的Task将结束生命周期,不再回调onFinished或者onNext方法。 ~~~java RxExecutor.getInstance() .executeTask(new Task( //配置失败重试 TaskBuilder.create() .setRetryMaxCount(3) ) { @Override public void run (Emitter emitter) throws Exception { super.run(emitter); //当前为子线程 //模拟子线程任务 Thread.sleep(1000); //任务结束 } @Override public void onError (Exception e) { super.onError(e); //任务出错 } @Override public void onFinished () { super.onFinished(); //当前为主线程 // 执行主线程逻辑 } }); ~~~ #### 场景8 ##### **任务组**
任务组是一种比较不常见的场景,比如开启双线程分别写入两个文件到内存卡,并且两个文件完成写入后退出界面。这时候就可以使用任务组概念进行 ~~~java RxExecutor.getInstance() .executeTaskGroup(GroupTaskBuilder.create() .setResultTask(new GroupResultTask() { @Override public void oneTaskComplete (Object tag, Object result) { result("任务" + tag.toString() + "执行结束,数据为:" + result, R.color.task_color_4); } @Override public void allTaskComplete (HashMap resultMap) { StringBuilder result = new StringBuilder(); for (Object o : resultMap.keySet()) { result.append(o.toString()); result.append(":"); result.append("" + resultMap.get(o)); } result("组任务全部完毕,数据为:" + result.toString(), R.color.task_color_4); } }) .setGroupStrategy(GroupTaskStrategy.ALL_COMPLETE) .addGroupTask(mGroupTask1) .setResultTag(1) .addGroupTask(mGroupTask2) .setResultTag(2) .addGroupTask(mGroupTask3) .setResultTag(3) .build()); ~~~ GroupResultTask是用来监控任务组执行结果的,每个任务执行完毕后会回调一次oneTaskComplete,所有任务执行完毕后会回调一次allTaskComplete,两个方法的参数列表返回了单个任务执行的数据结果,通过配置的tag进行判断,当然如果你不关心执行结果数据则可以不必调用setResultTag给每个任务设置tag。
任务组的执行模式有三种,通过setGroupStrategy方法进行设置(使用默认模式可以不调用这个方法): ~~~java /** * 默认模式 * 全部完成模式,全部任务执行完毕后 * 回调结果 * 使用此模式,如果组任务配置了失败 * 重试,则最终回调会等待组任务重试成功 * 组任务配置了任务重试会阻塞结果回调时机 */ public static final int ALL_COMPLETE = 0; /** * 错误退出模式 * 一个组任务发生错误则暂停其他任务 * 并不再继续 */ public static final int ERROR_EXIT = 1; /** * 错误忽略模式 * 一个任务发生的错误将会被忽略 * 其他任务正常执行,并待其他任务执行后 * 继续后续任务,使用此模式会忽略任务重试功能 * 组任务配置了任务重试不会阻塞结果回调时机 */ public static final int ERROR_IGNORE = 2; ~~~ 需要注意的是ALL_COMPLETE和ERROR_IGNORE的阻塞区别,主要来源于子任务的重试策略对他们产生的不同影响。

如果你的任务组中,有一个是必要的(必须完成,不完成会影响后续逻辑),其他是非必要的(顺便执行的任务,不关心是否成功),该怎么办?
不用担心,RxTask可以在组策略下配置单个任务的策略,比如下面的示例,任务1和3为非核心逻辑,2为核心逻辑,那么只需要如下配置即可保证任务1和3失败后对最后的任务组完成回调不产生影响。
~~~java RxExecutor.getInstance() .executeTaskGroup(GroupTaskBuilder.create() .setResultTask(new GroupResultTask() { @Override public void oneTaskComplete (Object tag, Object result) { result("任务" + tag.toString() + "执行结束,数据为:" + result, R.color.task_color_4); } @Override public void allTaskComplete (HashMap resultMap) { StringBuilder result = new StringBuilder(); for (Object o : resultMap.keySet()) { result.append(o.toString()); result.append(":"); result.append("" + resultMap.get(o)); } result("组任务全部完毕,数据为:" + result.toString(), R.color.task_color_4); } }) .setGroupStrategy(GroupTaskStrategy.ALL_COMPLETE) //非核心业务,可以允许失败 .addGroupTask(mGroupTask1) .setStrategy(GroupTaskStrategy.ERROR_IGNORE) .setResultTag(1) //核心业务,必须成功才进行下一步 .addGroupTask(mGroupTask2) .setResultTag(2) //非核心业务,可以允许失败 .addGroupTask(mGroupTask3) .setStrategy(GroupTaskStrategy.ERROR_IGNORE) .setResultTag(3) .build()); ~~~ **使用单任务策略需要注意以下几点**
首先,单任务的执行策略仅在任务组策略为GroupTaskStrategy.ALL_COMPLETE时才有效。
其次,任务组策略为GroupTaskStrategy.ALL_COMPLETE且没有配置单任务策略时,需要小心任务阻塞的处理,因为在此模式下,任何一个子任务执行失败都会造成你的后续逻辑执行不到,所以需要考虑每个任务失败时的处理逻辑。子任务出错参考前面Task任务出错时的情况。
最后,在activity中使用任务组时请务必绑定生命周期,以免出现内存泄漏问题。 #### 场景9 ##### 多种类型数据结果
一个子线程任务过程中可能产生不同结果或者多个结果,那么可以采用下面的写法(注意使用 emitter.objNext发射数据,用onObjNext接收数据),此方法可以用来控制多种类型或者多个步骤的子线程任务,每种类型或者步骤识别使用code来进行 ~~~java RxExecutor.getInstance() .executeTask(new Task() { @Override public void run (Emitter emitter) throws Exception { super.run(emitter); Thread.sleep(1000); //执行结果数据类型1 emitter.objNext("数据1", 1); Thread.sleep(1000); //执行结果数据类型2 emitter.objNext(222, 2); Thread.sleep(1000); //执行结果数据类型3 emitter.objNext(new Bundle(), 3); } @Override public void onObjNext (int code, Object obj) { super.onObjNext(code, obj); switch (code) { case 1: //处理数据类型1 break; case 2: //处理数据类型2 break; case 3: //处理数据类型3 break; default: break; } } }); ~~~ #### 场景10 ##### 常用子任务封装
以下三种类型均支持绑定生命周期,绑定生命周期后,生命周期结束,将不再回调 ##### 倒计时
~~~java RxExecutor.getInstance() .executeTask(new RxHelper.CountDownTask(60*1000,1000) { @Override public void count (long time) { } }); ~~~ ##### 延时任务
~~~java RxExecutor.getInstance() .executeTask(new RxHelper.DelayTask(60*1000) { @Override public void timeOver () { } }); ~~~ ##### 循环任务
-1表示无限循环 ~~~java RxExecutor.getInstance() .executeTask(new RxHelper.RecycleTask(1000,-1) { @Override public void count (int count) { } }); ~~~