Страницы

Поиск по вопросам

пятница, 14 февраля 2020 г.

Оптимальное количество элементов подгружаемых из SQLite в RecyclerView за один запрос

#android #sqlite #recyclerview


Есть новостной агрегатор. Статьи грузятся из сети, и хранятся в локальной SQLite.
UI организован стандартно: RecyclerView, элементами которого являются превью статей. 

Вопрос следующий: как оптимально организовать подгрузку данных в RecyclerView из
SQLite, если на экране помещается ≈ 3 элемента?

Поясню: в данном вопросе временем загрузки статей из сети, их размещением в БД и
временем преобразования статей в превью пренебрегаем. Интересует механизм подгрузки
элементов в RecyclerView за один запрос и организация этой подгрузки. Стандартный механизм
(загружаем сколько-то элементов -> пользователь прокручивает список до конца -> загружаем
новую порцию элементов) не подходит.

Например, возможно стоит ловить скроллинг на середине списка и уже тогда начинать
подгрузку новых данных? Кроме того, возможно у уважаемого сообщества есть опыт о том,
какое количество элементов из SQLite оптимально забирать за один запрос? Т.к. есть
подозрение, что загрузка 3 элементов из SQLite будет примерно равна по времени загрузке
30 элементов, т.к. большая часть времени тратится на саму транзакцию, но уже скажем
запрашивать 300 элементов за запрос будет неоптимально. 
    


Ответы

Ответ 1



@pavloff, конечно все верно расписал: за один запрос нужно "забирать" все нужные данные, нет никакого смысла делить их на маленькие части. Такое применимо к сетевым запросам, но никак не к локальным БД. Cursor сам подгрузит что надо, в нужном ему количестве, насколько мне помниться. В любом случае не стоит делать из этого проблем Но проблема в том, что RecyclerView из коробки не умеет поддерживать адаптер с курсором, то есть надо самому заморачиваться с изобретением адаптера, который будет читать из БД или же придумывать адаптер, который работает поверх Cursor, по аналогии с CursorAdapter, который имеется в комплекте ListView. К счастью умные люди уже все написали все. Возьмите RecyclerViewCursorAdapter - подайте ему на вход заранее подготовленный Cursor и будет вам счастье

Ответ 2



Разобрался в проблеме. Представлю свой ответ. Во-первых, почему для достаточно больших списков не стоит загружать сразу все данные для RecyclerView из SQLite: Нет смысла грузить данные, которые пользователь, возможно, не увидит. Если при той же отзывчивости интерфейса (без тормозов), мы можем обеспечить плавную подгрузку данных и, при этом, наше приложение будет кушать меньше памяти, то почему бы не сделать так? Использование SQLiteCursor имеет ту особенность, что при выборке данных размером больше 2 MB появляются дополнительные расходы по времени на выборку каждых следующих 2 MB данных. Речь о том, что размер используемого SQLiteCursor буфера строк (CursorWindow) около 2 MB. Более подробно об этой проблеме см. в этой статье: оригинал (en) и перевод на русский. Существуют решения по плавной подгрузке данных в RecyclerView из SQLite: см., например, этот цикл статей (en). Есть данные, что оптимально загружать за один раз не менее чем в 10 раз больше элементов RecyclerView, чем помещается на экране. Т.е., если на экране 3 элемента, подгружаем за один раз около 30. Подгрузку следующей порции данных, следует начинать на половине или 2/3 скроллинга до конца списка. Это общие советы, т.к. стоит учитывать размер данных, возможное их преобразование в POJO-объекты для списка, особенности реализации RecyclerView. Наконец, есть библиотека от Google Paging Library (еще не вышла в релиз 1.0), которая призвана в том числе решать проблему, затронутую в вопросе. Еще один пример, реализация подгрузки c использованием RxJava (1 часть, 2 часть).

Комментариев нет:

Отправить комментарий