You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在RecyclerAdapter ViewHolder中实现LifecycleOwner并正确调用onDestroy

解决方案:LifecycleViewHolder的onDestroy()调用位置

你需要在两个位置调用该方法,覆盖所有销毁场景:

1. Adapter的onViewRecycled回调

这是ViewHolder被系统回收、不再用于展示数据时的标准回调,直接在你的自定义LifecyclePagingDataAdapter中重写该方法即可:

abstract class LifecyclePagingDataAdapter<T: Any, VH: LifecycleViewHolder>(diffCallback: DiffUtil.ItemCallback<T>) : PagingDataAdapter<T, VH>(diffCallback) {

    override fun onViewAttachedToWindow(holder: VH) {
        super.onViewAttachedToWindow(holder)
        holder.onAppear()
    }

    override fun onViewDetachedFromWindow(holder: VH) {
        super.onViewDetachedFromWindow(holder)
        holder.onDisappear()
    }

    // 新增如下代码
    override fun onViewRecycled(holder: VH) {
        super.onViewRecycled(holder)
        holder.onDestroy()
    }
}

2. 列表宿主(Activity/Fragment)销毁时主动调用

当列表所在的页面整体销毁时,当前还在屏幕上展示的ViewHolder不会触发onViewRecycled回调,需要主动遍历所有附着的ViewHolder调用销毁方法,避免内存泄漏:
首先在Adapter中新增工具方法:

fun destroyAllHolders(recyclerView: RecyclerView) {
    recyclerView.children.forEach { childView ->
        (recyclerView.getChildViewHolder(childView) as? VH)?.onDestroy()
    }
}

然后在宿主的销毁生命周期中调用,例如Fragment的onDestroyView:

override fun onDestroyView() {
    super.onDestroyView()
    yourAdapter.destroyAllHolders(yourRecyclerView)
}

补充适配:支持ViewHolder复用

官方LifecycleRegistry不允许从DESTROYED状态回退到活跃状态,如果你需要复用ViewHolder,需要调整LifecycleViewHolder的代码适配场景:

abstract class LifecycleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), LifecycleOwner {
    // 改为var,支持复用场景重置
    private var lifecycleRegistry = LifecycleRegistry(this)

    init {
        resetLifecycleState()
    }

    private fun resetLifecycleState() {
        lifecycleRegistry = LifecycleRegistry(this)
        lifecycleRegistry.currentState = Lifecycle.State.INITIALIZED
        lifecycleRegistry.currentState = Lifecycle.State.CREATED
    }

    fun onAppear() {
        // 复用场景下先重置状态
        if (lifecycleRegistry.currentState == Lifecycle.State.DESTROYED) {
            resetLifecycleState()
        }
        lifecycleRegistry.currentState = Lifecycle.State.STARTED
        lifecycleRegistry.currentState = Lifecycle.State.RESUMED
    }

    fun onDisappear() {
        lifecycleRegistry.currentState = Lifecycle.State.STARTED
        lifecycleRegistry.currentState = Lifecycle.State.CREATED
    }

    fun onDestroy(){
        lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
    }

    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistry
    }
}

完成上述修改后,你在ViewHolder中绑定的LiveData Observer会在DESTROYED触发时被自动移除,lifecycle.coroutineScope启动的协程也会被自动取消,不需要额外手动清理。

内容的提问来源于stack exchange,提问作者John Santos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 09:36:02