Kotlin入门(29)任务Runnable
任务Runnable定义了一个可以独立运行的代码片段,通常用于界面控件的延迟处理,比如有时为了避免同时占用某种资源造成冲突,有时则是为了反复间隔刷新界面从而产生动画效果。运行一个任务也有多种形式,既可在UI线程中调用处理器对象的post或者postDelayed方法,也能另外开启分线程来执行Runnable对象。那么在运行任务之前,必须事先声明该任务的对象,然后才能由调用者执行该任务。Kotlin代码声明Runnable对象有四种方式,分别对应不同的业务场景,接下来就依次阐述Runnable对象的四种声明方式:
第一种:内部类
内部类方式是最循规蹈矩的,在代码里先书写一个继承自Runnable的内部类,再重写它的run方法,填入具体的业务逻辑处理。以最常见的计数器为例子,每隔一秒便在界面上显示加一后的计数结果,使用内部类方式进行变化的话,就是以下的Kotlin代码:
private val handler = Handler()private var count = 0inner private class Counter : Runnable {override fun run() {count++tv_result.text = "当前计数值为:$count"handler.postDelayed(this, 1000)}}
然后在Activity页面的onCreate方法中加上下面一行代码,命令执行这个计数任务:
handler.post(Counter())
第二种:匿名内部类
内部类的方式最正规,无疑也是最啰嗦的。由于这个计数任务只在页面打开时启动,因此并不需要对其显式构造,只要在定义内部类时顺便声明任务实例即可。此时的声明代码便从内部类方式变成了匿名内部类方式,采取Kotlin编码的话注意使用关键字object占位,表示这是一个匿名内部类,完整的Kotlin代码如下所示:
private val counter = object : Runnable {override fun run() {count++tv_result.text = "当前计数值为:$count"handler.postDelayed(this, 1000)}}
因为定义内部类的同时就声明了任务实例,所以处理器直接运行该实例即可启动任务:
handler.post(counter)
内部类与匿名内部类这两种方式,其实内部都拥有类的完整形态,故而它们的run方法允许使用关键字this指代这个人物类,示例代码中的“handler.postDelayed(this, 1000)”意思是间隔一秒之后重复执行自身任务。正因为能够重复执行任务,所以这两种方式可用于持续刷新界面的动画效果。
第三种:匿名函数
前面的两种内部类实现方式,拥有类的完整形态意味着必须显式重写run方法,可是这个任务类肯定且只能重写run方法,即使开发者不写出来,run方法也是逃不掉的。早在第一章,当时为了演示Kotlin代码的间接性,举了一个例子“按钮对象.setOnClickListener { 点击事件的处理代码 }”,这种写法正是采取了Lamba表达式,直接把点击事件接口的唯一方法onClick给省略掉。因此,本节的任务对象也可使用类似的写法,只要说明该对象是Runnable类型,则多余的run方法就能如愿去除。下面是个将任务对象改写后的Kotlin代码:
private val counter = Runnable {count++tv_result.text = "当前计数值为:$count"}
显而易见,上述的counter仍是Runnable类型,于是处理器依旧运行该实例即可启动任务:
handler.post(counter)
不过这种写法去掉run方法是有代价的,虽然表面上代码变得简洁,但是并不拥有类的完整结构,其内部的this关键字不再表示任务类自身,而是表示宿主类即Activity活动类了。鉴于这点变化,该方式内部不可再调用处理器的post或者postDelayed方法,意味着此时任务实例无法重复调用自身。因此,采取了匿名函数方式的任务对象,适用于不需要重复刷新的场合。
第四种:匿名实例
注意到前面的counter是个经过等号赋值的任务对象,既然这样,不如直接把等号右边的表达式塞进post方法,就像下面的Kotlin代码那样:
//第1点:在post方法中直接填写Runnable对象的定义代码handler.post(Runnable {count++tv_result.text = "当前计数值为:$count"})
上面的代码还可以进一步精简,因为post方法只能输入Runnable类型的参数,所以括号内部的Runnable纯属多余;另外,post方法有且仅有一个输入参数,于是圆括号嵌套大括号稍显繁琐。把这两个冗余之处分别删除与合并,得到了匿名实例版的Kotlin代码:
//第2点:如果该任务只需执行一次,则可采用匿名实例的方式,直接嵌入任务的执行代码handler.post {count++tv_result.text = "当前计数值为:$count"}
上述去掉圆括号的办法,只适合post方法这种仅有一个参数的调用,如果其它方法存在多个输入参数如postDelayed方法,则外层的圆括号仍需予以保留,此时大括号及其内部代码就作为一个函数参数传入。恢复了圆括号的Kotlin调用代码如下所示:
//第3点:如果是延迟执行任务,则可将匿名实例作为postDelayed的输入参数handler.postDelayed({count++tv_result.text = "当前计数值为:$count"}, 1000)
匿名实例方式直接把任务代码写在调用函数之中,意味着这段任务代码无法被其他地方调用,所以它的适用场景更加狭小。匿名函数虽然无法重复调用,但是尚且允许在不同地方多次调用,而匿名实例只能在它待过的地方昙花一现,因此还是要根据实际的业务要求来选择合适的任务方式。
点此查看Kotlin入门教程的完整目录
__________________________________________________________________________
打开微信扫一扫下面的二维码,或者直接搜索公众号“老欧说安卓”添加关注,更快更方便地阅读技术干货。
Kotlin入门(29)任务Runnable相关推荐
- Kotlin入门教程——目录索引
Kotlin是谷歌官方认可的Android开发语言,即将发布的Android Studio 3.0版本也会开始内置Kotlin,所以未来在App开发中Kotlin取代Java是大势所趋,就像当初And ...
- Kotlin入门(14)继承的那些事儿
上一篇文章介绍了类对成员的声明方式与使用过程,从而初步了解了类的成员及其运用.不过早在<Kotlin入门(12)类的概貌与构造>中,提到MainActivity继承自AppCompatAc ...
- Kotlin入门(5)字符串及其格式化
上一篇文章介绍了数组的声明和操作,包括字符串数组的用法.注意到Kotlin的字符串类也叫String,那么String在Java和Kotlin中的用法有哪些差异呢?这便是本文所要阐述的内容了. 首先要 ...
- Kotlin入门(33)运用扩展属性
进行App开发的时候,使用震动器要在AndroidManifest.xml中加上如下权限: <!-- 震动 --><uses-permission android:name=&quo ...
- Kotlin入门(32)网络接口访问
手机上的资源毕竟有限,为了获取更丰富的信息,就得到辽阔的互联网大海上冲浪.对于App自身,也要经常与服务器交互,以便获取最新的数据显示到界面上.这个客户端与服务端之间的信息交互,基本使用HTTP协议进 ...
- Kotlin入门(31)JSON字符串的解析
json是App进行网络通信最常见的数据交互格式,Android也自带了json格式的处理工具包org.json,该工具包主要提供了JSONObject(json对象)与JSONArray(json数 ...
- Kotlin入门(30)多线程交互
Android开发时常会遇到一些耗时的业务场景,比如后台批量处理数据.访问后端服务器接口等等,此时为了保证界面交互的及时响应,必须通过线程单独运行这些耗时任务.简单的线程可使用Thread类来启动,无 ...
- Kotlin入门(28)Application单例化
Application是Android的又一大组件,在App运行过程中,有且仅有一个Application对象贯穿应用的整个生命周期,所以适合在Application中保存应用运行时的全局变量.而开展 ...
- Kotlin入门(26)数据库ManagedSQLiteOpenHelper
共享参数毕竟只能存储简单的键值对数据,如果需要存取更复杂的关系型数据,就要用到数据库SQLite了.尽管SQLite只是手机上的轻量级数据库,但它麻雀虽小.五脏俱全,与Oracle一样存在数据库的创建 ...
最新文章
- CRF算法中辅助概念 团 极大团 最大团
- mysql选定数据库_mysql数据库学习――2,数据库的选定,创建,删除和变更_MySQL...
- UVALive 3905 Meteor (扫描线)
- meta标签的使用方法(PC端)
- 【OpenJudge - noi - 7624】山区建小学(dp)
- Invitation Cards POJ 1511
- docker k8s helm常用命令梳理
- 【Java】反射、枚举、Lambda表达式
- c语言实验答案周信东综合程序设计,周信东主编最新版-C语言程序设计基础实验一实验报告.doc...
- Lumerical---FDTD仿真区域设置问题
- mysql多表查询去重复数据_SQL重复记录查询 查询多个字段、多表查询、删除重复记录的方法...
- undo歌词中文音译_Undo - Sanna nielsen帮我看看这歌词翻译对么
- 设置TextView滚动
- 微信公众号如何设置开发者密码(APPSecret)?
- 新手如何学习学嵌入式开发?
- java ext.dirs_关于-Djava.ext.dirs使用问题
- Python接口测试实战1(下)- 接口测试工具的使用
- 悼念512汶川大地震遇难同胞——重建希望小学 ( )
- webpackvue-cli快速构建
- 软件工程师杰夫的个人营销实例(十分钟看完系列)
热门文章
- 吴恩达深度学习神经网络基础编程作业Building your Deep Neural Network Step by Step
- 正点原子操作过程中芯片总是出错
- 如何用1年时间获得3年成长?
- 第三:Python发送邮件时中文附件下载乱码
- java was datasource_mybatis默认的数据源连接池(PooledDataSource和UnPooledDataSource)
- [Ext JS 4] 实战之Load Mask - 在Grid Reconfigure的使用状况
- android pdf生成 路径,android – 如何从指向PDF文档的URI获取文件路径?
- 引入SpringBoot Jpa依赖后,项目出现警告
- 计算机组成微程序操作码怎么写,计算机组成原理学习笔记——控制器
- 小米互联通信服务_时隔六年,小米NFC碰碰贴复活,碰一下自动亮灯、联网、投屏...