在 Kotlin 中,Handler
通常用于 Android 开发中的线程间通信(如主线程与后台线程的交互),但需要结合 Looper
使用。以下是 详细使用场景、代码示例及注意事项:
一、Handler 核心作用
-
线程间通信:将任务发送到指定线程(如主线程)执行。
-
延迟执行:安排任务在未来的某个时间点执行。
-
定时任务:周期性执行任务(需配合
postDelayed
)。
二、基本用法(主线程)
1. 创建 Handler(主线程)
// 在主线程创建 Handler(自动关联主线程的 Looper)
val mainHandler = Handler(Looper.getMainLooper())
// 发送任务到主线程执行
mainHandler.post {
// 更新 UI 操作,例如修改 TextView
textView.text = "主线程任务执行"
}
// 延迟执行(2秒后执行)
mainHandler.postDelayed({
textView.text = "延迟2秒执行"
}, 2000)
2. 在后台线程发送任务到主线程
// 在协程或其他后台线程中
lifecycleScope.launch(Dispatchers.IO) {
// 模拟耗时操作
delay(1000)
// 通过 Handler 切回主线程更新 UI
mainHandler.post {
textView.text = "后台线程完成任务,主线程更新"
}
}
三、避免内存泄漏(重要!)
在 Activity/Fragment 中使用 Handler
时,若未正确释放,可能导致内存泄漏。以下是 安全写法:
1. 使用 WeakReference
class MyActivity : AppCompatActivity() {
private var handler: Handler? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 使用 WeakReference 包裹 Activity
val weakActivity = WeakReference(this)
handler = Handler(Looper.getMainLooper()) {
// 处理消息
weakActivity.get()?.handleMessage(it)
true
}
}
private fun handleMessage(msg: Message) {
// 处理消息逻辑
}
override fun onDestroy() {
super.onDestroy()
handler?.removeCallbacksAndMessages(null) // 移除所有任务
}
}
2. 结合 Lifecycle
class LifecycleAwareHandler(
private val lifecycle: Lifecycle,
looper: Looper,
private val callback: (Message) -> Boolean
) : Handler(looper) {
init {
// 当生命周期销毁时移除所有回调
lifecycle.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
removeCallbacksAndMessages(null)
lifecycle.removeObserver(this)
}
})
}
override fun handleMessage(msg: Message) {
if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
callback(msg)
}
}
}
四、替代方案(协程)
现代 Android 开发中,协程(Coroutines) 更推荐用于异步任务和线程切换:
// 在后台执行耗时任务
lifecycleScope.launch(Dispatchers.IO) {
// 模拟耗时操作
delay(1000)
// 切回主线程更新 UI
withContext(Dispatchers.Main) {
textView.text = "使用协程更新 UI"
}
}
// 延迟执行
lifecycleScope.launch(Dispatchers.Main) {
delay(2000)
textView.text = "协程延迟2秒执行"
}
建议:
-
新项目优先使用 协程 处理异步任务。
-
维护旧代码或需要精确控制任务时,使用
Handler
但注意内存安全。