假设存在一个可观察对象,它生成非常大(10,000+元素)集合的序列。这个可观察对象在后台线程上工作,然后将结果传递给UI线程,其中RecyclerView适配器添加每个字符串。一般来说,有两种方法可以将每个列表拆分为单独的字符串:
- 在工作线程中,在可观察对象本身中(发出的不是集合,而是字符串)。
在第一种情况下,UI做了一个小工作。这对于应用程序响应性非常重要。但是由于在线程之间传输每个字符串的开销,处理数据的总体时间也可能显著增加,从而降低应用程序的性能。
你认为你更喜欢哪种方法?
示例代码。
方法1,在后台线程上处理数据:
Observable.create(subscriber -> {
// Data is transferred from background to UI thread 10,000 times.
for (int i = 0; i < 10000; i++)
subscriber.onNext("String " + i);
})
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.newThread())
.subscribe(data ->
RecyclerView.Adapter adapter = ...;
// UI holds for processing just one string.
adapter.add(data);
});
方法2,在UI线程上处理数据:
Observable.create(subscriber -> {
Collection<String> data = new ArrayList<>();
for (int i = 0; i < 10000; i++) data.add("String " + i);
// Data transfers from background to UI thread only once
subscriber.onNext(data);
})
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.newThread())
.subscribe(data -> {
RecyclerView.Adapter adapter = ...;
// Long operation, UI waits until all 10,000 element will be processed.
for (String e : data)
adapter.add(e);
});
恕我冒昧,我将采用第三种方法。
stringsObservable.buffer(1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.newThread)
.observeOn(AndroidSchedulers.mainThread)
.subscribe(adapter::addAll)
缓冲区的原因是,如果您快速添加项目,您将使recyclerView失败。缓冲区的时间,或者使用更简单的缓冲区(nItems),这是需要调优的。
只是测试和决定什么实际上更适合您(像往常一样,当我们谈到性能时)。我建议您不要局限于这两种变体。还要考虑传递给10-100个字符串的适配器块的中间变体。