NotifyDataSetChanged- RecyclerView – это асинхронный вызов?

Я пытаюсь выполнить набор инструкций после выполнения notifyDataSetChanged в recyclerview. Но когда я отлаживаю свое приложение, отладчик достигает следующих нескольких строк после моего notifyDataSetChanged перед notifyDataSetChanged как перейти к onBindViewHolder адаптера onBindViewHolder . Итак, мой вопрос: is notifyDataSetChanged асинхронный вызов? Если да, мы получаем обратный вызов? PS: Я уже пробовал этот ответ, и я не мог найти подходящего ответа, поэтому я спрашиваю сообщество.

RecyclerView автор здесь,

Когда вы вызываете notifyDataSetChanged , RecyclerView аннулирует данные, но не обновляет пользовательский интерфейс до следующего кадра анимации. Вот как работает система просмотра андроида. Когда виджет недействителен (например, меняет его данные), он запрашивает макет, который означает, что он будет повторно измерен и перераспределен на следующем просмотре. Это делается для того, чтобы мы могли выполнять все изменения до следующего обновления экрана. Вот почему notifyDataSetChange не вызывает onBind мгновенно.

Так что да, вы можете назвать это как асинхронный вызов, но это не значит, что вы можете запускать его многопоточным (это две совершенно разные концепции). Вы все равно должны внести все изменения в свой адаптер в основном потоке. Когда вы меняете адаптер, вы должны немедленно уведомить RecyclerView, поэтому уведомление также должно быть в основном потоке.

Причина этого ограничения заключается в том, что если набор данных изменяется во время компоновки, менеджеру макета очень сложно восстановить стабильное состояние (например, представьте, что вызовы RecyclerView onBind(5) и элемент 5 удаляются в другом потоке на в то же время). Кроме того, для учета таких изменений потребуется большая синхронизация, что будет большим штрафом за производительность без какой-либо выгоды. Вот почему все компоненты пользовательского интерфейса являются однопоточными.

TLDR : Нет. Вы можете вызвать notifyDatasetChanged() только из потока пользовательского интерфейса, как указано здесь, в котором изменения в пользовательском интерфейсе могут выполняться только в основном потоке. Это делает синхронный вызов.

Этот вызов предназначен для перерисовки ui с измененными элементами. Это похоже на вызов функции requestFocus() в представлении.

Из документации :

RecyclerView попытается синтезировать видимые события структурных изменений для адаптеров, которые сообщают, что они имеют стабильные идентификаторы при использовании этого метода. Это может помочь в целях сохранения анимации и визуального объекта, но отдельные представления элементов все равно нуждаются в отскоке и восстановлении.

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

У вас может быть несколько AdapterObservers, которые могут выполнять действия, которые вам нужны на ui.

Также из документации:

  • Это событие не указывает, что изменило набор данных, заставив * любых наблюдателей предположить, что все существующие элементы и структура могут быть более недействительными. * LayoutManagers будут вынуждены полностью переустановить и передать все видимые виды.

По умолчанию наблюдатель предположит, что все данные были изменены, поскольку из исходного кода представления Recycler:

  public final void notifyDataSetChanged() { mObservable.notifyChanged(); } 

Это синхронный вызов, которого следует избегать и использовать в качестве последнего средства .