简介
基于kotlin coroutine的Channel,实现的一个非阻塞式的任务队列,按先进先出的规则执行任务。
适用场景
适用于多个任务没有依赖关系,需要排队执行的情况。
比如:多个UI展示任务,需要排队一一展示的情况
- 弹框任务编排,例如,app首页有多个弹框(隐私弹框、权限弹框、更新弹框、运营弹框),需要按一定顺序排队展示,一个接一个展示,并且上一个主动关闭之后才能下一个。
- 直播间打赏礼物展示,打赏礼物动画需要一个一个展示的场景,动画展示的时间固定的。
引用
库在jitpack上
| 1 | maven { url 'https://jitpack.io' } | 
| 1 | dependencies { | 
特性
- 基于kotlin coroutine实现。
- First-In,First-out处理任务
- 支持指定task执行在主线程或是子线程
使用
- 创建任务队列管理类 - 1 - mQueueManager = TaskQueueManager() 
- 添加任务(有固定执行时间的) - 1 
 2
 3- mQueueManager.sendTask(Task(3000) { 
 ToastUtils.showShort("btn click: $curCount ,counts")
 })
- 添加执行时间不固定的任务(展示一个弹框) - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10- mQueueManager.sendTask(Task { 
 PopTip.show("弹框提示: $curCount", "关闭").noAutoDismiss()
 .setButton { popTip, v -> //点击“撤回”按钮回调
 //延迟1s展示下一个任务
 this@MainActivity.mViewBinding.btnShot.postDelayed(1000) {
 doNextTask()
 }
 false
 }
 })
执行时间不确定的任务,需要在任务执行完后主动调用 doNextTask() 方法去执行下一个task,否则消费者会一直挂起。
注意:还提供了一个全局单例TaskQueueManager.instance
分析
task定义
一类task是有固定执行时间的,比如展示一个toast,每次都是展示2s;一类task是没有固定的执行时间的,比如,app首页各种类型的弹框,权限弹框没有依赖信息,直接展示,如果不关闭的话,会一直展示,表示任务一直在执行中,只有当用户手动关闭弹框时,任务才结束。task可以执行在主线程,也可以执行在子线程处理耗时任务。执行完当前任务之后会执行下一个任务。
task支持指定要执行在主线程(默认),还是子线程,如果是执行时间固定的支持指定执行时间,默认是执行时间不固定。
| 1 | /** | 
队列处理
使用channel构造的生产者,消费者的多对一模型,消费者在消费task时,生产者被挂起。使用RENDEZVOUS类型的channel,没有缓冲区,同一时刻只能执行一个task,当执行taks,挂起send操作。执行task时切换到指定的Dispatchers.MAIN或者Dispatchers.IO协程上下文执行,如果task是执行时间不固定,使用Mutex挂起channel的receive操作所在的coroutine,当task执行完毕的恢复channel的receive操作所在的coroutine,同时send操作所在coroutine被恢复执行。