Android开发中,只能是UI线程才可以更新UI界面,否则会抛出异常。除了UI线程意外的其他线程都被称为子线程。我们通常所说的多线程可以直接理解为多个子线程。
在Java里面,要开启子线程,有三种方案:
一是继承自Thread;
二是实现Runable接口;
三是线程池技术。
但面对多任务处理的多线程需求是,还是推荐线程池来实现,这样可以避免线程反复的创建和收回,造成的资源浪费;同时由于消线程池内部实现了对线程的自我管理,这样能够大大的提高线程的使用效率。对于偶尔需要的子线程操作,推荐实现Runable接口的方案,因为该方案是通过接口实现,避免了继承的单一性,方便功能的扩张。
在Kotlin里面,实现线程是非常简单的,现在我们来看看Kotlin里面实现子线程的两种方式以及子线程通过Handler更新UI:
方式一、直接通过Thread实现子线程并通过Handler更新UI:
logging("Kotlin里面主线程:${Thread.currentThread().name}")
Thread{
logging("Kotlin里面直接通过Thread的子线程:${Thread.currentThread().name}")
var message = Message()
message.obj = "Ktlin里面更新UI?"
mHandler.sendMessage(message)
}.start()
Thread(CustomThred()).start()
方式二、通过实现Runnable接口实现子线程:
logging("Kotlin里面主线程:${Thread.currentThread().name}")
Thread(CustomThred()).start()
inner class CustomThred : Runnable {
override fun run() {
logging("通过实现Runnable接口的子线程::${Thread.currentThread().name}")
}
}
Handler的实现:
var mHandler = Handler{
var str:String = it.obj.toString()
logging("通过Handler接收到的数据:$str")
btnThread.text = Editable.Factory.getInstance().newEditable(str)
etMod.hint = Editable.Factory.getInstance().newEditable(str)
false
}
上面的代码中,两条打印日志的结果如下图:
我们可以看到通过Thread{……}我们创建了一个子线程,并且成功获取到了该子线程的名字。然后我们通过Handler对象和message对象发送了一条消息更新UI。
在Handler对象创建这一步,我们通过lambda表达式极简化的创建一个Handler对象。然后lambda表达式下的Handler的it对象就是一个Message对象,我们可以直接使用。然后我们通过获取到的信息分别更新了按钮Button的显示内容和输入框EditText的hint提示值。
强调一个重点!强调一个重点!!强调一个重点!!!重要的事情说三遍:注意Handler对象里面的加粗标红的false返回值,这个一定不能少,熟悉Handler用法的开发者都应该知道为什么这里不能省去这个false;