Java中使用Handler相信大家都知道,所以这篇文章就告诉大家在Kotlin中怎么使用Handler
对kotlin函数不太了解的同学可以看看这篇文章
kotlin基本函数的使用 - 简书 (jianshu.com)
一. 最简写法
class MainActivity : AppCompatActivity() {
private val WHAT = 100
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Thread {
mHandler.sendMessage(Message.obtain().apply {
what = WHAT
obj = "你好"
})
}.start()
}
private val mHandler = Handler(mainLooper) {
when (it.what) {
WHAT -> Log.d("mHandler:", "${it.obj}")
}
false
}
}
以上写法是经过高阶函数和lambda表达式简化的,实际调用的是两个参数的构造方法,闭包是Callback.handleMessage,所以需要有一个返回值。
public Handler(@NonNull Looper looper, @Nullable Callback callback) {
this(looper, callback, false);
}
匿名内部类会持有外部类的引用,所以mHandler会持有MainActivity的引用,Message又会持有mHandler的引用,等于Message间接持有了MainActivity的引用。如果通过mHandler发送的是延迟消息,那么在Message进入消息队列等待的过程中会一直持有MainActivity的引用,即使MainActivity在等待消息送达的过程中finish掉了也不会被系统回收,这样就造成了Handler引起的内存泄漏问题。
二. 无内存泄漏写法
class MainActivity : AppCompatActivity() {
private lateinit var tvName: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
tvName = findViewById(R.id.tv_name)
Thread {
mHandler.sendMessageDelayed(Message.obtain().apply {
what = WHAT
obj = "你好"
}, 5000)
}.start()
}
private val mHandler = MyHandler(WeakReference(this))
private class MyHandler(val wrActivity: WeakReference<MainActivity>) : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
wrActivity.get()?.run {
when (msg.what) {
WHAT -> tvName.text = msg.obj as String
}
}
}
}
companion object {
const val WHAT = 100
}
}
实现原理与Java版一样,也是通过WeakReference弱引用方式解决。这里是重写的父类Handler的handleMessage,所以不需要返回值。