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

使用Dagger+RxJava更新RecyclerView时列表无限刷新问题排查

问题分析与解决方案

看起来你的代码里藏着一个无限循环触发网络请求的坑,这才导致列表每秒都刷新一次。我来帮你把问题拆解开:

核心问题:无限循环调用loadData()

仔细看你的ContactsViewModel代码:

fun getContactMutableLiveData(): MutableLiveData<List<ContactsModel>> {
    loadData() // 每次调用这个方法都会触发一次网络请求
    return mutableLiveData
}

// 请求成功的回调里:
override fun onSuccess(t: List<ContactsModel>) {
    getContactMutableLiveData().value = t // 这里调用了getContactMutableLiveData(),又会触发loadData()
}

当第一次网络请求成功后,你通过getContactMutableLiveData().value = t更新LiveData,但这个方法内部会再次调用loadData()发起新请求。新请求成功后又重复这个流程,直接形成了无限循环——每完成一次请求就立刻开启下一次,所以日志会显示每秒刷新一次(对应每次网络请求的响应周期)。

而你的Java项目里应该是直接给LiveData赋值,没有通过getContactMutableLiveData()方法,所以没触发这个循环。

修复方案

首先解决最核心的循环问题,修改onSuccess里的代码,直接给mutableLiveData赋值,绕开getContactMutableLiveData():

override fun onSuccess(t: List<ContactsModel>) {
    mutableLiveData.value = t // 直接设置LiveData的值,不再触发新的请求
}

另外还有几个优化建议,让代码更健壮:

  • 避免重复创建Adapter和LayoutManager:你的Activity观察者回调里,每次数据更新都重新创建Adapter、设置LayoutManager,这完全没必要。建议在onCreate里一次性初始化布局和Adapter,只在回调里更新数据:

    // Activity的onCreate中初始化一次
    recycler_contacts.layoutManager = LinearLayoutManager(applicationContext, OrientationHelper.VERTICAL, false)
    recycler_contacts.setHasFixedSize(true)
    mAdapter = ContactsAdapter(this@ContactListActivity, arrayListOf())
    recycler_contacts.adapter = mAdapter
    
    // 观察者回调里只更新数据
    contactsViewModel.getContactMutableLiveData().observe(this@ContactListActivity, Observer {
        mAdapter.updateData(it as ArrayList<ContactsModel>)
        mAdapter.sortByName()
    })
    

    记得在ContactsAdapter里添加updateData方法,更新数据集后调用notifyDataSetChanged()(用DiffUtil做局部刷新会更高效)。

  • 清理ViewModel的Disposable:重写onCleared()方法清空订阅,避免内存泄漏:

    override fun onCleared() {
        super.onCleared()
        disposable.clear()
    }
    
  • 避免重复发起请求:修改getContactMutableLiveData(),只有当LiveData为空时才加载数据:

    fun getContactMutableLiveData(): MutableLiveData<List<ContactsModel>> {
        if (mutableLiveData.value.isNullOrEmpty()) {
            loadData()
        }
        return mutableLiveData
    }
    

这样修改后,无限循环的问题就解决了,列表只会在首次启动时加载一次数据,后续有需要时再触发更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 08:12:44