Handler的实例化一般是在主线程中的,用于对ui的更新,在主线程中实例化时默认与主线程的looper绑定了,无须手动绑定。Handler的runable执行也是默认在looper绑定的线程中执行的。
在activity的create中执行以下就知道了:
Handler().postDelayed({
try {
RequestApiManager.shared.checkAppUpdateInfo(this, "")//检测是否更新
LogUtils.e("", "1线程id" + Thread.currentThread().id.toString() + "")`
} catch (e: Exception) {
e.printStackTrace()
}
}, 5000)
LogUtils.e("", "2线程id" + Thread.currentThread().id.toString() + "")
会发现以上打印的id是一样的。
Handler也可以在子线程中实例化,但是需要手动绑定looper,调用
Looper.prepare(),最后Looper.loop(),进行绑定。这种情况是不能更新ui的
例如:
LogUtils.e("", "2线程id" + Thread.currentThread().id.toString() + "")
//不需要ui操作的子线程
Thread() {
Looper.prepare()
val handler = Handler()
//定时心跳包发送
try {
val runnable = object : Runnable {
override fun run() {
RequestApiManager.shared.postHeartbeet()
handler.postDelayed(this, 5000)//设置心跳是400s一次心跳,这里参考新版qq心跳是180s,微信300s
LogUtils.e("", "子线程2" + Thread.currentThread().id.toString() + "")
}
}
handler.postDelayed(runnable, 10000)//打开应用后10秒后开始发送第一次心跳包*/
} catch (e: Exception) {
LogUtils.e(this.javaClass.toString(), e.message)
}
Looper.loop() //此方法调用后后面的方法不会被执行
}.start()
会发现2个打印的线程id是不一样的。
Handler在子线程中也实例化并且绑定主线程的looper,然后进行更新ui。
LogUtils.e("", "2线程id" + Thread.currentThread().id.toString() + "")
//不需要ui操作的子线程
Thread() {
Looper.prepare()
val handler = Handler(Looper.getMainLooper())
//定时心跳包发送
try {
val runnable = object : Runnable {
override fun run() {
RequestApiManager.shared.postHeartbeet()
handler.postDelayed(this, 5000)//设置心跳是400s一次心跳,这里参考新版qq心跳是180s,微信300s
LogUtils.e("", "子线程2" + Thread.currentThread().id.toString() + "")
}
}
handler.postDelayed(runnable, 10000)//打开应用后10秒后开始发送第一次心跳包*/
} catch (e: Exception) {
LogUtils.e(this.javaClass.toString(), e.message)
}
Looper.loop()//此方法调用后后面的方法不会被执行
}.start()
}
这种情况id一样,都是主线程id,是可以更新ui的。因为只有主线程可以更新ui,
val handler = Handler(Looper.getMainLooper())
是绑定主线程的looper,并且runable执行也是主线程中执行的,需要注意耗时操作不建议放在主线程