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

使用DisposableObserver时无法更新ListView?技术求助

解决RxAndroid搜索数组更新ListView卡顿崩溃的问题

Hey there! Let's work through your RxAndroid issue—lagging and crashing when searching an array to update a ListView is super common for folks new to Rx, so let's break this down step by step.

First, let's spot the likely culprits in your code snippet:

1. 你可能在主线程执行了耗时搜索

If you're running that Observable.create logic on the main thread (which is the default if you don't specify otherwise), searching through a large array will block the UI thread—this causes the lag, and if it takes too long, you'll get an ANR (Application Not Responding) crash.

2. 代码里有明显的拼写错误

Your snippet shows $wo... which looks like a typo for $word—this invalid regex pattern would throw an exception, leading to a crash.

3. 没有正确切换线程

RxJava's power comes from thread scheduling! You need to run the heavy search work on a background thread, then switch back to the main thread only for UI updates.


修正后的完整代码示例

Here's how to adjust your code to fix these issues:

val dataArray = ArrayList<CisData>()
lateinit var cisDataAdaptor: CisDataAdaptor
var isFirst = true

// 正确的RxJava搜索逻辑
Observable.create(ObservableOnSubscribe<CisData> { emitter ->
    val searchWord = "Test"
    // 修正拼写错误,构建正确的模糊匹配正则(忽略大小写可加RegexOption.IGNORE_CASE)
    val searchRegex = ".*$searchWord.*".toRegex()

    // 遍历数组,把匹配的数据发送出去
    dataArray.forEach { cisData ->
        // 假设你要匹配CisData里的某个字段,比如name或者content
        if (cisData.targetField.matches(searchRegex)) {
            emitter.onNext(cisData)
        }
    }
    emitter.onComplete() // 一定要调用onComplete,告诉观察者搜索结束
})
.subscribeOn(Schedulers.io()) // 把搜索任务放到IO线程执行,不卡主线程
.observeOn(AndroidSchedulers.mainThread()) // 切换回回主线程更新UI
.subscribe(object : Observer<CisData> {
    private val matchedResults = ArrayList<CisData>()

    override fun onSubscribe(d: Disposable) {
        // 可选:这里可以显示加载动画或者提示
    }

    override fun onNext(cisData: CisData) {
        // 收集所有匹配的数据
        matchedResults.add(cisData)
    }

    override fun onError(e: Throwable) {
        // 处理错误,比如打印日志或者给用户提示
        Log.e("RxSearchError", "Search failed", e)
        Toast.makeText(context, "搜索出错啦", Toast.LENGTH_SHORT).show()
    }

    override fun onComplete() {
        // 更新适配器并刷新ListView
        cisDataAdaptor.clear() // 先清空原有数据(如果需要)
        cisDataAdaptor.addAll(matchedResults)
        cisDataAdaptor.notifyDataSetChanged()

        // 处理首次加载的逻辑
        if (isFirst) {
            isFirst = false
            // 比如初始化一些其他UI元素
        }
    }
})

额外的优化建议

  • 管理Disposable:记得把这个订阅的Disposable存起来(比如用CompositeDisposable),在Activity/Fragment的onDestroy方法里调用disposable.dispose(),避免内存泄漏。
  • 优化搜索效率:如果不需要复杂的正则匹配,用contains代替matches会更快,比如cisData.targetField.contains(searchWord, ignoreCase = true)。
  • 考虑用RecyclerView代替ListView:RecyclerView有更好的性能优化(比如ViewHolder复用、局部刷新),比ListView更适合处理大量数据。
  • 避免频繁发送onNext:如果你的数组特别大,发送单个List<CisData>而不是逐个发送CisData对象会更高效——可以用Observable.just()或者Single来返回整个匹配列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:15:05