2016-08-16 1 views
1

Предположим, что существует наблюдаемая, которая генерирует последовательности очень больших (10 000+ элементов) Collection. Этот наблюдаемый работает в фоновом потоке, а затем передает результат в поток пользовательского интерфейса, где адаптер RecyclerView добавляет каждую из строк. В общем, есть два подхода, где разделить каждый из списков на отдельных строках:Android, RX: что помещено в пользовательский интерфейс - коллекции или элементы?

  1. В наблюдаемом самом (испускает не коллекции, а строка), на рабочем потоке.
  2. В подписчике, в потоке пользовательского интерфейса.

В первом случае пользовательский интерфейс выполняет небольшую работу. Это важно для применения отзывчивость Но из-за накладные расходы для передачи каждой строки между потоками, общее время обработки данных также может значительно увеличиться, понижая производительность приложения.

Как вы думаете, какой подход вы предпочитаете?

Пример кода.

подход 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); });

+0

Я не уверен, как выглядят два разных подхода. Можете ли вы добавить код? Обычно у меня есть мой подписчик в списке , вызывайте адаптер.swapItems (список), который уведомляет, что набор данных изменил и повторно заселяет recyclerview, что я считаю тем, что делает ваш вариант 2. Я не уверен, что вы представляете для варианта 1. – AdamMc331

+0

Добавлен код, например. – Alexey

ответ

0

Просто тест и решить, что на самом деле работает лучше вы (как обычно, когда говорим о производительности). Я советую вам не ограничивать себя двумя вариантами. Рассмотрим также промежуточные варианты, проходящие к переходным блокам 10-100 строк.

2

IMHO Я возьму третий подход.

stringsObservable.buffer(1, TimeUnit.SECONDS) 
    .subscribeOn(Schedulers.newThread) 
    .observeOn(AndroidSchedulers.mainThread) 
    .subscribe(adapter::addAll) 

Причина буфера заключается в том, что вы добавляете элементы, которые быстро заставят recyclerView сработать. Время для буфера или использование более простого буфера (nItems) - это то, что нужно настроить.

Смежные вопросы