Kotlin Thread线程与UI更新详解
作者:go2coding 发布时间:2021-10-10 00:18:22
多线程的好处是不言而喻的,它能帮我们刚更多的事情,同时干不同的事情在程序设计中是经常出现的,这种时候我们使用的是线程。
在Kotlin
中,使用的还是原先java
的那一套,用的还是Thread
,可能是在java
中Thread
就挺好用的,Kotlin
没有做太多的变化。
线程Thread的使用
Thread
是一个类,有几种用法,比较常规的是声明一个类,继承Thread
,重载run()
的方法,后建立一个变量,使用start
的方法启动线程。
inner class CountThread:Thread(){
var passc:Int = 0
override fun run() {
super.run()
while (true){
Thread.sleep(1000)
passc ++
println("A second has passed,${passc}")
}
}
}
CountThread
就是一个线程类,它负责数数,每隔一秒钟数一次,并打印出来,这里来启动他。
var countT = CountThread()
countT.start()
这里每隔一秒钟,打印一次记录。
I/System.out: A second has passed,1
I/System.out: A second has passed,2
I/System.out: A second has passed,3
I/System.out: A second has passed,4
I/System.out: A second has passed,5
I/System.out: A second has passed,6
I/System.out: A second has passed,7
I/System.out: A second has passed,8
I/System.out: A second has passed,9
I/System.out: A second has passed,10
同样的如果代码比较简洁,可以用如下的代码来定义和启动线程。
Thread {
var passc:Int = 0
while (true){
Thread.sleep(1000)
passc ++
println("A second has passed,${passc}")
}
}.start()
在线程中更新UI
如果我们直接在线程中更新UI,会出现什么?我们想把数据直接显示在TextView
中,在线程中这样写:
Thread {
var passc:Int = 0
while (true){
Thread.sleep(1000)
passc ++
println("A second has passed,${passc}")
tv_count.setText("A second has passed,${passc}")
}
}.start()
在线程中直接设置 tv_count.setText("A second has passed,${passc}")
,但是很不幸,出现了如下的错误。
Process: com.kotlin.kotlin_start_ch18, PID: 24758
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:11131)
这也是一个常见的错误,在很多的语言编程中,是不能直接在线程中更新ui界面的,因为界面有自己的ui线程,需要到他自己的线程中才能更新。
那怎么办呢?
把数据发送出来,在ui的线程中更新就可以了。在线程中,使用Handler
,相当于把消息发送到主线程中。
inner class MessageHandler: Handler(){
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
tv_count.setText(msg.obj.toString())
}
}
在线程中把数据发送出来:
Thread {
var passc:Int = 0
while (true){
Thread.sleep(1000)
passc ++
println("A second has passed,${passc}")
//tv_count.setText("A second has passed,${passc}")
var message = Message()
message.obj = "A second has passed,${passc}"
messageHandler.sendMessage(message)
}
}.start()
这样就能成功的在界面上更新ui。
小结
线程是我们在多任务的时候,进程要考虑的一种方法,他又经常很ui界面挂钩,在大部分的编程语言里,更新ui都必须在ui线程里。这里的线程看起来都比较的简单,但是真正的在项目中使用线程的话,就务必要多注意了,因为他很容易出现资源互锁的情况。
来源:https://blog.csdn.net/weixin_40425640/article/details/128032061


猜你喜欢
- 引言最近的项目需求中有使用到后端发送http请求,在网上寻找资料后发现可以使用spring自带的RestTemplate类实现,故作此记录项
- 一、只读自动属性(Read-only auto-properties) C# 6之前我们构建只读自动属性: public stri
- 一、二维数组进入正题之前.首先为了便于大家理解,我画了一个图:xx枪战游戏中, 我是一个刚刚注册账号的小白,系统送了我两把枪,此时,我的武器
- Sentinel 是什么随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统
- string filePath = @"E:\Randy0528\中文目录\JustTest.rar"; &n
- 在微服务中,需要我们在各个微服务中共享Session,使用Redis来共享Session是一个很好的解决方法,Redis是运行在内存中,查取
- 最近用到需要无限轮播自动播放的轮播轮播图,网上感觉都有这样那样的问题,于是自己写了一个通用的控件CarouselFigureView。特点:
- Android 中Manifest.xml文件详解每一个Android项目都包含一个清单(Manifest)文件--AndroidManif
- 1 C++类型转换本质1.1 自动类型转换(隐式)利用编译器内置的转换规则,或者用户自定义的转换构造函数以及类型转换函数(这些都可以认为是已
- 本文实例讲述了C#将HashTable中键列表或值列表复制到一维数组的方法。分享给大家供大家参考。具体如下:下面的示例说明如何将 Hasht
- 0、线程的本质线程不是一个计算机硬件的功能,而是操作系统提供的一种逻辑功能,线程本质上是进程中一段并发运行的代码,所以线程需要操作系统投入C
- 本文以实例形式较为全面的讲述了C++的多重继承与虚继承,是大家深入学习C++面向对象程序设计所必须要掌握的知识点,具体内容如下:一、多重继承
- if语句一个if语句包含一个布尔表达式和一条或多条语句。语法If语句的用语法如下:if(布尔表达式){ //如果布尔
- 一、简述1、AOP的概念如果你用java做过后台开发,那么你一定知道AOP这个概念。如果不知道也无妨,套用百度百科的介绍,也能让你明白这玩意
- 关于java的字符串处理我们一般使用String类和StringBuffer类那么String类和StringBuffer类的区
- .c 源程序 ----- 编译 ----- 链接 ---- exe ----运行 -------->程序翻译环境和执行环境翻译环境:源
- Android上使调用OpenCV 2.4.10 实现二维码区域定位(Z-xing 码),该文章主要用于笔者自己学习中的总结,暂贴出代码部分
- 前言最近在开发一个IM项目的时候有一个需求就是,好友搜索功能。即在EditText中输入好友名字,ListView列表中动态展示刷选的好友列
- android开机自动运行APP实现方式其实很简单。在android系统运行时,会发出“android.intent.action.BOOT
- The java.io.Writer.flush() method flushes the stream. If the stream ha