android 之 Kotlin中Handler的使用
在 Android Kotlin 开发中,Handler
主要用于线程间通信(如后台线程更新 UI)和延迟任务调度。以下是关键用法、示例及注意事项,结合最佳实践和内存安全方案:
class MainActivity : AppCompatActivity() {private lateinit var binding: ActivityMainBinding// 绑定主线程 Looperprivate val mainHandler = Handler(Looper.getMainLooper())override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)// 在后台线程执行耗时任务thread {Thread.sleep(2000) // 模拟耗时操作// 通过 Handler 切回主线程更新 UImainHandler.post {binding.textView.text = "后台任务完成,主线程更新 UI"}}}
}
关键点:
Handler(Looper.getMainLooper())
确保任务在主线程执行。场景:网络请求、数据库读写等后台操作后更新 UI。
2. 延迟执行任务
// 延迟 3 秒显示 Toast
mainHandler.postDelayed({Toast.makeText(this, "延迟 3 秒执行", Toast.LENGTH_SHORT).show()
}, 3000)
注意:时间单位是毫秒(3000ms = 3s
)
二、避免内存泄漏(安全写法)
Handler
持有 Activity
引用可能导致内存泄漏。解决方案:
方案 1:静态内部类 + 弱引用
class SafeHandlerActivity : AppCompatActivity() {private lateinit var weakHandler: WeakReferenceHandlercompanion object {const val MSG_UPDATE_TEXT = 1}// 静态内部类,不持有外部引用class WeakReferenceHandler(activity: SafeHandlerActivity) : Handler(Looper.getMainLooper()) {private val weakRef = WeakReference(activity)override fun handleMessage(msg: Message) {val activity = weakRef.get() ?: returnwhen (msg.what) {MSG_UPDATE_TEXT -> activity.binding.textView.text = "安全更新文本"}}}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)weakHandler = WeakReferenceHandler(this)// 发送延迟消息weakHandler.sendEmptyMessageDelayed(MSG_UPDATE_TEXT, 2000)}override fun onDestroy() {super.onDestroy()weakHandler.removeCallbacksAndMessages(null) // 移除所有回调}
}
方案 2:结合 Lifecycle
class LifecycleAwareHandler(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)}}
}
优势:自动在 onDestroy
时清理消息
三、替代方案:协程(推荐)
现代 Android 开发中,协程更简洁且避免内存泄漏:
class CoroutineActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)lifecycleScope.launch(Dispatchers.IO) {delay(2000) // 后台延迟 2 秒withContext(Dispatchers.Main) {binding.textView.text = "协程更新 UI"}}// 主线程延迟任务lifecycleScope.launch(Dispatchers.Main) {delay(3000)Toast.makeText(this@CoroutineActivity, "协程延迟任务", Toast.LENGTH_SHORT).show()}}
}
依赖
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.8.0"
五、总结建议
场景 | 推荐方案 | 理由 |
---|---|---|
简单 UI 更新 |
| 代码简洁 |
复杂生命周期任务 |
| 自动清理消息,避免泄漏 |
新项目/异步任务 | 协程 | 语法简洁、安全,官方推荐 |
定时循环任务 |
| 精确控制间隔(需注意泄漏) |