什么是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: 让线程任务的使用变得高效、安全、方便、灵活相关推荐

  1. Android开源项目分类汇总-转载

    太长了,还是转载吧... 今天在看博客的时候,无意中发现了@Trinea在GitHub上的一个项目Android开源项目分类汇总,由于类容太多了,我没有一个个完整地看完,但是里面介绍的开源项目都非常有 ...

  2. Android开源项目分类汇总[转]

    Android开源项目分类汇总 如果你也对开源实现库的实现原理感兴趣,欢迎 Star 和 Fork Android优秀开源项目实现原理解析 欢迎加入 QQ 交流群:383537512(入群理由需要填写 ...

  3. Android开源项目第二篇——工具库篇

    本文为那些不错的Android开源项目第二篇--开发工具库篇,主要介绍经常使用的开发库,包含依赖注入框架.图片缓存.网络相关.数据库ORM建模.Android公共库.Android 高版本号向低版本号 ...

  4. Android开源项目--分类汇总

    为什么80%的码农都做不了架构师?>>>    转自:https://github.com/Trinea/android-open-project Android开源项目第一篇--个 ...

  5. 六款值得推荐的Android开源框架简介

    六款值得推荐的Android开源框架简介 技术不再多,知道一些常用的.不错的就够了.下面就是最近整理的"性价比"比较高的Android开源框架,应该是相对实用的. 1.volley ...

  6. Android 开源框架选择

    目录 一.前言 二.APP的整体架构 三.技术选型的考量点 四.日志记录能力 五.JSON解析能力 1.gson 2.jackson 3.Fastjson 4.LoganSquare 六.数据库操作能 ...

  7. Android中使用Thread线程出现的问题

    很多初入Android或Java开发的新手对Thread.Looper.Handler和Message仍然比较迷惑,衍生的有HandlerThread.java.util.concurrent.Tas ...

  8. android开源库收集

    1. google valley Android网络通信库 git clone https://android.googlesource.com/platform/frameworks/volley ...

  9. Android开源框架源码鉴赏:LruCache与DiskLruCache

    关于作者 郭孝星,程序员,吉他手,主要从事Android平台基础架构方面的工作,欢迎交流技术方面的问题,可以去我的Github提issue或者发邮件至guoxiaoxingse@163.com与我交流 ...

  10. android开源2016_2016年十大开源项目

    android开源2016 每年涌现,壮大,改变和发展的精彩的开源项目继续给我们留下深刻的印象. 从我们的年度最佳项目清单中选出10个绝非易事,当然,这份简短的清单也不能囊括每个值得开展的项目. 为了 ...

最新文章

  1. 刚开始Windows Mobile的开发,请大家多多关照
  2. 【深度学习】煮酒论英雄:深度学习CV领域最瞩目的top成果总结
  3. 计算机操作系统——处理机调度算法
  4. 案例:Xshell 成功创建定时任务(解决no crontab for root using an empty one问题)- 最新版
  5. 定时关机 v1.0(autoshut v1.0)
  6. 阶乘末尾连续零的个数
  7. stride padding_关于Padding实现的一些细节
  8. From Apprentice To Artisan 翻译 08
  9. 聚焦开源技术 第八届开源云黑客松活动举办在即
  10. Python——jieba分词并统计词频
  11. 光伏行业MES管理系统解决方案
  12. 网站SQL注入漏洞检测
  13. 2021春招美团算法笔试题
  14. 罗振宇《时间的朋友2018》跨年演讲全文
  15. 仓储系统主要注意事项
  16. android dialog遮挡键盘,彻底解决软键盘遮挡DialogFragment
  17. iOS开发 图片选择器、图片多选功能的实现
  18. 外业精灵,在水土流失监测野外调查工作中的应用
  19. mysql+下周,sql统计本周,本月,下周,下月sql语句
  20. 如何使用开源工具构建您的网络安全工具包

热门文章

  1. 7 分钟了解 eBay Flink 服务的端到端管理
  2. java使用httpClient解决外部url请求访问
  3. java中怎么创建单列模式,java中的3种方式创建的单例模式
  4. maximum call stack size exceeded ajax,Maximum call stack size exceeded error
  5. python开发环境有哪些_python开发环境哪个好用?如何搭建?
  6. pythonATM,购物车项目实战_补充7-start.py
  7. mac input 不支持xls_如何将PDF转换成xls格式的表格
  8. CS224N刷题——Assignment3.1_A window into NER
  9. javaSpring面试题,安排
  10. Hadoop基础-HDFS数据清理过程之校验过程代码分析