[Android开源]EasyExecutor: 让线程任务的使用变得高效、安全、方便、灵活
什么是EasyExecutor
EasyExecutor是开源基础组件集成库EasyAndroid中的基础组件之一。
其作用是:对线程池进行二次封装,为上层提供最简单、最方便的线程操作体验
EasyAndroid作为一款集成组件库,此库中所集成的组件,均包含以下特点,你可以放心使用~~
1. 设计独立
组件间独立存在,不相互依赖,且若只需要集成库中的部分组件。也可以很方便的
只copy对应的组件文件
进行使用
2. 设计轻巧
因为是组件集成库,所以要求每个组件的设计尽量精练、轻巧。避免因为一个小功能而引入大量无用代码.
每个组件的方法数均
不超过100
. 大部分组件甚至不超过50
。
得益于编码时的高内聚性
,若你只需要使用EasyExecutor. 那么可以直接去拷贝EasyExecutor源码文件到你的项目中,直接进行使用,也是没问题的。
EasyAndroid开源库地址:
https://github.com/yjfnypeu/EasyAndroid
EasyExecutor组件地址:
https://github.com/yjfnypeu/EasyAndroid/blob/master/utils/src/main/java/com/haoge/easyandroid/easy/EasyExecutor.kt
特性
- 安全: 直接catch住任务执行期间出现的异常。并通知给用户,避免出现crash
- 回调通知: 执行任务期间,有分别的生命周期作为通知。
- 配置灵活: 可方便、灵活的对每次所启动的任务,配置线程名、回调等。
- 任务延迟: 支持在每次启动任务前。指定延迟时间
- 异步任务: 支持直接启动异步任务并回调传递数据
- 线程切换: 支持指定回调方法所在的线程。默认为运行于UI线程中
- 进度通知: 支持方便地进行任务处理进度通知
用法
创建配置EasyExecutor实例
EasyExecutor是对线程池进行的封装,所以在创建时,我们需要指定需要创建的线程池的大小
val builder = EasyExecutor.newBuilder(size)
... // 其他配置
val executor = builder.build()// 配置完成后再创建EasyExecutor提供使用
复制代码
参数size为Int
类型,即为指定的线程池大小
,size与创建的线程池的关系为:
val executor = when {// size小于1, 创建可缓存大小的线程池提供使用size <= 0 -> Executors.newCachedThreadPool(createFactory())// size大于0, 创建指定大小的线程池。else -> Executors.newFixedThreadPool(size, createFactory())
}
复制代码
线程优先级配置
可以通过以下方式,指定线程池创建出来的线程优先级
:
builder.setPriority(priority)
复制代码
线程任务名配置
所谓任务名
即是创建出来的线程的线程名
, 而指定任务名的方式有以下两种:
1.指定默认任务名:在创建时进行指定
builder.setName("default name")
复制代码
2.指定临时任务名:在使用前进行指定
executor.setName("temp name")
复制代码
临时
与默认
任务名的关系是:在启动一次后台任务时:
- 当
有配置临时任务名
时:使用临时任务名
作为此次的线程任务名,并将此临时任务名进行重置
- 当
没配置临时任务名
时:使用默认任务名
作为此次的线程任务名。
启动异步任务
普通异步任务,直接创建任务进行启动即可:
executor.execute { // TODO }
复制代码
很多时候,在java原生中的使用习惯是:普通任务都是通过Runnable
接口进行定义,所以EasyExecutor
也提供了直接使用Runnable
任务的重载方法:
val runnable:Runnable = createTask()
executor.execute(runnable)
复制代码
启动异步回调任务
异步回调任务:用于在需要接收异步任务返回值时使用:
executor.async(task:(Notifier) -> T, // Notifier将在后面的进度通知小节进行介绍result:(T)->Unit)// 接收task的返回值并通知到此
复制代码
比如说。在子线程进行Bitmap创建:
executor.async({ // 异步任务// 子线程中,进行Bitmap创建,return@Callable bitmap},{ bitmap -> // 异步回调,默认运行于UI线程// TODO 使用创建好的bitmap进行操作// 关于回调线程的派发,后面 派发器 小节会进行详细说明}
)
复制代码
启动延迟任务
如果需要指定此次任务
需要被延迟执行
时。使用setDelay
直接指定延迟时间
即可:
executor.setDelay(delayTime)
复制代码
请注意: delayTime
类型为Long
, 单位为毫秒
。且此延迟时间
的有效作用域是此次被启动的任务
。一旦有任务被启动之后。延迟时间
将被重置。也就是:
executor.setDelay(3000)
executor.execute(task1)// task1任务将被延迟3秒执行
executor.execute(task2)// task2任务将被直接执行
复制代码
安全的进行回调派发
EasyExecutor
提供三个回调方法:
类型 | lambda | 说明 |
---|---|---|
onStart | (String) -> Unit |
当线程任务被执行时被触发,参数为任务名
|
onError | (String, Throwable) -> Unit |
当线程任务执行出现异常时被触发, 参数为任务名 和出现的异常
|
onSuccess | (String) -> Unit |
当线程任务执行完成时被触发,参数为任务名
|
此三种回调,也有默认回调配置
和临时回调配置
的区别
指定默认回调:作用域为所有的线程任务
builder.onStart {threadName -> } // 所有任务启动时的回调.onSuccess {threadName -> }// 所有任务执行完毕后的回调.onError {threadName, throwable -> }// 所有任务执行出现异常时的回调
复制代码
指定临时回调:作用域为此次启动的线程任务
executor.onStart {threadName -> } // 此次任务启动时的回调.onSuccess {threadName -> }// 此次任务执行完毕后的回调.onError {threadName, throwable -> }// 此次任务执行出现异常时的回调
复制代码
所以,与任务名配置
不同。临时回调不会覆盖掉默认回调,而他们被触发的先后顺序是:先触发默认回调。再触发临时回调
而所谓安全
,即是在整个任务的执行过程中。会将执行过程中出现的异常
进行捕获。防止任务执行出错导致crash
。被捕获的异常将会通过onError
回调。通知到指定线程进行处理:
Thread.currentThread().setUncaughtExceptionHandler {name, e ->// deliver:派发器。将消息通知到指定线程。deliver.execute {builder.error?.invoke(name, e)// 默认回调异常通知error?.invoke(name, e)// 临时回调异常通知}
}
复制代码
配置派发器
就以上面的三个回调方法
为例:我们在说的时候。只说了它们被触发的时机,但是没说它们具体运行在哪个线程中。而这,就是派发器干的事:
派发器的作用: 就是将消息派发到指定线程中去之后再进行用户通知!
派发器的本质,是一个Executor
接口的实现类:
internal var deliver:Executor = UIDeliver
复制代码
而默认使用的UIDeliver
,就是专门针对Android运行时环境
创建的:将消息派发到UI线程进行通知
internal val UIDeliver:Executor = Executor { runnable ->if (Looper.myLooper() == Looper.getMainLooper()) {runnable.run()} else {mainHandler.post { runnable.run() }}
}
复制代码
而对于派发器来说。也存在默认配置
与临时配置
默认配置:当不存在临时派发器配置时,使用此默认派发器
builder.setDeliver(Executor {})
复制代码
临时配置:只对此次启动任务生效
executor.setDeliver(Executor {})
复制代码
需要注意的是:派发器也对异步回调任务生效
。所以在默认配置下,异步回调也是运行于UI线程中的:
executor.async(Callable<T> {return T},{ T ->// 此回调所处线程也受派发器控制。}
)
复制代码
进行异步任务进度通知
有些时候,我们会需要在任务的处理过程中,对外进行进度状态通知,以便进行上传的进度UI更新。使用EasyExecutor
。也可以很方便的做到进度通知的效果:
需要进行状态通知,首先需要定制进度回调通知:
executor.onProgressChanged { current:Long, total:Long ->// 传参current为当前的进度, total为数据总量。// 此回调所处线程也受派发器控制
}
复制代码
而EasyExecutor
本身提供的任务模型
就提供了有进行外部状态通知的实例:
// 普通任务:
executor.execute { notifier -> }
// 异步任务
executor.async( { notifier -> }, { result -> })
复制代码
任务实例中的传参notifier即是用于进行外部通知的类。对于需要监听状态通知的任务。可以通过此实例方便的指定进度信息。
所以一个完整的进度回调任务
模型应该是如以下代码一样:
executor.onProgressChanged { current, total -> TODO("进行进度变化通知展示")}.execute { notifier -> // 在合适的处理进度中。使用以下api进行进度状态派发即可notifier.progressChanged(current, total)}
复制代码
欢迎扫描下方二维码关注我的公众号?
[Android开源]EasyExecutor: 让线程任务的使用变得高效、安全、方便、灵活相关推荐
- Android开源项目分类汇总-转载
太长了,还是转载吧... 今天在看博客的时候,无意中发现了@Trinea在GitHub上的一个项目Android开源项目分类汇总,由于类容太多了,我没有一个个完整地看完,但是里面介绍的开源项目都非常有 ...
- Android开源项目分类汇总[转]
Android开源项目分类汇总 如果你也对开源实现库的实现原理感兴趣,欢迎 Star 和 Fork Android优秀开源项目实现原理解析 欢迎加入 QQ 交流群:383537512(入群理由需要填写 ...
- Android开源项目第二篇——工具库篇
本文为那些不错的Android开源项目第二篇--开发工具库篇,主要介绍经常使用的开发库,包含依赖注入框架.图片缓存.网络相关.数据库ORM建模.Android公共库.Android 高版本号向低版本号 ...
- Android开源项目--分类汇总
为什么80%的码农都做不了架构师?>>> 转自:https://github.com/Trinea/android-open-project Android开源项目第一篇--个 ...
- 六款值得推荐的Android开源框架简介
六款值得推荐的Android开源框架简介 技术不再多,知道一些常用的.不错的就够了.下面就是最近整理的"性价比"比较高的Android开源框架,应该是相对实用的. 1.volley ...
- Android 开源框架选择
目录 一.前言 二.APP的整体架构 三.技术选型的考量点 四.日志记录能力 五.JSON解析能力 1.gson 2.jackson 3.Fastjson 4.LoganSquare 六.数据库操作能 ...
- Android中使用Thread线程出现的问题
很多初入Android或Java开发的新手对Thread.Looper.Handler和Message仍然比较迷惑,衍生的有HandlerThread.java.util.concurrent.Tas ...
- android开源库收集
1. google valley Android网络通信库 git clone https://android.googlesource.com/platform/frameworks/volley ...
- Android开源框架源码鉴赏:LruCache与DiskLruCache
关于作者 郭孝星,程序员,吉他手,主要从事Android平台基础架构方面的工作,欢迎交流技术方面的问题,可以去我的Github提issue或者发邮件至guoxiaoxingse@163.com与我交流 ...
- android开源2016_2016年十大开源项目
android开源2016 每年涌现,壮大,改变和发展的精彩的开源项目继续给我们留下深刻的印象. 从我们的年度最佳项目清单中选出10个绝非易事,当然,这份简短的清单也不能囊括每个值得开展的项目. 为了 ...
最新文章
- 刚开始Windows Mobile的开发,请大家多多关照
- 【深度学习】煮酒论英雄:深度学习CV领域最瞩目的top成果总结
- 计算机操作系统——处理机调度算法
- 案例:Xshell 成功创建定时任务(解决no crontab for root using an empty one问题)- 最新版
- 定时关机 v1.0(autoshut v1.0)
- 阶乘末尾连续零的个数
- stride padding_关于Padding实现的一些细节
- From Apprentice To Artisan 翻译 08
- 聚焦开源技术 第八届开源云黑客松活动举办在即
- Python——jieba分词并统计词频
- 光伏行业MES管理系统解决方案
- 网站SQL注入漏洞检测
- 2021春招美团算法笔试题
- 罗振宇《时间的朋友2018》跨年演讲全文
- 仓储系统主要注意事项
- android dialog遮挡键盘,彻底解决软键盘遮挡DialogFragment
- iOS开发 图片选择器、图片多选功能的实现
- 外业精灵,在水土流失监测野外调查工作中的应用
- mysql+下周,sql统计本周,本月,下周,下月sql语句
- 如何使用开源工具构建您的网络安全工具包
热门文章
- 7 分钟了解 eBay Flink 服务的端到端管理
- java使用httpClient解决外部url请求访问
- java中怎么创建单列模式,java中的3种方式创建的单例模式
- maximum call stack size exceeded ajax,Maximum call stack size exceeded error
- python开发环境有哪些_python开发环境哪个好用?如何搭建?
- pythonATM,购物车项目实战_补充7-start.py
- mac input 不支持xls_如何将PDF转换成xls格式的表格
- CS224N刷题——Assignment3.1_A window into NER
- javaSpring面试题,安排
- Hadoop基础-HDFS数据清理过程之校验过程代码分析