使用DisposableObserver时无法更新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

