Android Kotlin 自定义View中添加延迟的最优实现方案是什么
方案优先级说明
优先选择协程+View生命周期作用域的方案,耦合度最低、自动处理生命周期、代码最简洁。
1. 最优方案:协程实现
需要先引入lifecycle-view-ktx依赖(项目已引入可跳过):
implementation "androidx.lifecycle:lifecycle-view-ktx:2.6.2"
在loadDetails()中直接使用View的lifecycleScope启动协程即可,该作用域会和View的生命周期绑定,View被移除时协程自动取消,不会执行后续逻辑,无需手动处理销毁。不需要使用Fragment的作用域,直接用View自身的作用域即可,避免和外部组件耦合:
fun loadDetails() { // 原有业务逻辑 lifecycleScope.launch { // 等待5秒 delay(5000) myadapter.notifyDataSetChanged() } }
2. RxJava Observable.timer 适配方案
如果项目技术栈以RxJava为主不想引入协程,可通过手动管理Disposable实现安全调用:
- 声明Disposable成员变量存储定时任务的引用:
private var timerDisposable: Disposable? = null
- 重写View的
onDetachedFromWindow方法,View被移除时销毁未执行的任务:
override fun onDetachedFromWindow() { super.onDetachedFromWindow() timerDisposable?.dispose() }
loadDetails()中的实现:
fun loadDetails() { // 先取消之前未执行的定时任务,避免重复触发 timerDisposable?.dispose() timerDisposable = Observable.timer( 5000L, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread() ).subscribe { myadapter.notifyDataSetChanged() } }
3. Handler.postDelay 优化方案
如果必须使用Handler实现,可通过主动移除回调规避风险:
- 声明Handler和执行任务的Runnable:
private val mainHandler = Handler(Looper.getMainLooper()) private val notifyTask = Runnable { myadapter.notifyDataSetChanged() }
- 重写
onDetachedFromWindow移除未执行的任务:
override fun onDetachedFromWindow() { super.onDetachedFromWindow() mainHandler.removeCallbacks(notifyTask) }
loadDetails()中的调用:
fun loadDetails() { // 先移除之前的任务,避免重复触发 mainHandler.removeCallbacks(notifyTask) mainHandler.postDelayed(notifyTask, 5000) }
内容的提问来源于stack exchange,提问作者Albertano Santacruz
相关产品推荐
相关产品推荐

