Будет ли привязка данных отменять регистрацию слушателей из ViewModel, реализующих Observable? - PullRequest
1 голос
/ 14 апреля 2020

У меня есть несколько более сложных логик c для данных, предоставленных моим ViewModel в пользовательский интерфейс, поэтому простое предоставление данных с помощью LiveData не справится со мной. Теперь я видел в Android документах , что я могу реализовать Observable на моем ViewModel, чтобы получить нужный мне мелкозернистый элемент управления.

Однако в документации это также говорится:

В некоторых ситуациях вы можете предпочесть использовать компонент ViewModel, который реализует интерфейс Observable, а не объекты LiveData, даже если вы потеряете возможности управления жизненным циклом LiveData .

Насколько интеллектуальна встроенная привязка данных Android? Будет ли он автоматически отменять регистрацию своих слушателей, когда это необходимо (например, при изменениях конфигурации, когда View разрушается), чтобы мне не пришлось беспокоиться о потерянных возможностях жизненного цикла? Или я должен смотреть Lifecycle of the View и отменять регистрацию его слушателей? (= делать вручную то, что обычно делает для меня LiveData).

Ответы [ 3 ]

1 голос
/ 24 апреля 2020

Насколько интеллектуальна встроенная привязка данных Android? Будет ли он автоматически отменять регистрацию своих слушателей, когда это необходимо (например, при изменениях конфигурации, когда View разрушается), чтобы мне не пришлось беспокоиться о потерянных возможностях жизненного цикла? Или я должен смотреть Lifecycle of the View и отменять регистрацию его слушателей? (= делать вручную то, что обычно делает для меня LiveData).

Итак, я провел несколько тестов. Я реализовал androidx.databinding.Observable на своем ViewModel и изменил конфигурацию со следующими вызовами журнала:

override fun removeOnPropertyChangedCallback(
    callback: androidx.databinding.Observable.OnPropertyChangedCallback?) {
    Log.d("APP:EVENTS", "removeOnPropertyChangedCallback " + callback.toString())
}

override fun addOnPropertyChangedCallback(
    callback: androidx.databinding.Observable.OnPropertyChangedCallback?) {
    Log.d("APP:EVENTS", "addOnPropertyChangedCallback " + callback.toString())
}

Я видел, что addOnPropertyChangedCallback вызывался каждый раз, когда на мою модель представления ссылались в выражении привязки макета , И ни разу я не видел, как вызывали removeOnPropertyChangedCallback. Мой первоначальный вывод заключается в том, что привязка данных AndroidX является глупой и не приводит к автоматическому удалению слушателя.
FYI: тип обратного вызова был ViewDataBinding.WeakPropertyListener

Однако я Взглянул на ViewDataBinding.java исходный код и обнаружил, что он использует Слабые ссылки для добавления прослушивателя.

Так что это означает, что при конфигурации измените, Android ОС должна быть в состоянии собрать мусор из вашей Деятельности / Фрагмента, потому что у модели представления нет сильной ссылки.

Мой совет: не добавляйте шаблон для отмены регистрации слушателей. Android не будет пропускать ссылки на ваши действия и фрагменты при изменениях конфигурации .

Теперь, если вы решите не использовать LiveData, подумайте над тем, чтобы ваша модель представления реализовала LifecycleObserver, чтобы вы могли повторно -испускать последнее значение, когда ваша активность / фрагмент переходит в активное состояние. Это ключевое поведение, которое вы теряете, если не используете LiveData. В противном случае вы можете отправлять уведомления, используя PropertyChangeRegistry.notifyCallbacks(), как указано в документации, которую вы предоставили в другой раз. К сожалению, я думаю, что это можно использовать только для уведомления о всех свойствах.

Другое дело ... хотя я не проверял поведение, исходный код, похоже, указывает на то, что слабые ссылки используются для ObservableField, ObservableList, ObservableMap и др. c.

LiveData отличается по нескольким причинам:

  1. )" rel="nofollow noreferrer"> В документации для LiveData.observe говорится, что строгая ссылка поддерживается как для наблюдателя, так и для жизненного цикла владелец, пока владелец жизненного цикла не будет уничтожен.
  2. LiveData испускает иначе, чем ObservableField. LiveData будет излучаться всякий раз, когда вызывается setValue или postValue независимо от того, действительно ли значение изменяется. Это не верно для ObservableField. По этой причине LiveData может использоваться для отправки «псевдо-события» путем установки одного и того же значения более одного раза. Пример того, где это может быть полезно, можно найти на странице Условная навигация , где несколько сбоев при входе в систему приводят к появлению нескольких «закусочных».
1 голос
/ 17 апреля 2020

Неа. ViewModel не отменяет регистрацию подписки Observable автоматически. Вы можете сделать это вручную, хотя. Это довольно просто.

  • Во-первых, вы создаете CompositeDisposable
    protected var disposables = CompositeDisposable()
  • Во-вторых, создайте свой Observable (это может быть некоторый запрос или пользовательский интерфейс) прослушиватель событий) подпишитесь на него и присвойте его результат CompositeDisposable
    disposables.add(
        someObservable
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({ data ->
                // update UI or some ObservableFields for view/databinding
            }, { exception ->
                // handle errors here
            })
    )
  • Последнее, что вы должны сделать, это переопределить ViewModel метод onCleared() следующим образом:
    override fun onCleared() {
        super.onCleared()
        disposables.clear()
    }

Таким образом, все подписки, добавленные к вашему CompositeDisposable, будут очищаться автоматически

Редактировать

Я показал только пример , Вы можете добавить триггеры в onConfigurationChanged или onCreate или onResume, чтобы также очистить подписки - но это зависит от конкретных c вариантов использования приложения. Я дал только общий.

Надеюсь, это поможет.

0 голосов
/ 22 апреля 2020

Привязка данных не сделает для вас отмену регистрации. Это просто поможет связать ваш файл макета и ViewModel. Именно ViewModel защитит вас от изменения конфигурации устройства. Вам все еще нужно применить onSavedViewState () в вашей основной деятельности или фрагменте, так как viewModel не покрывает это. Что касается отмены регистрации, LiveData делает это.

Как @Pavio уже научил вас, как создавать Observable, то есть Rx Java работает. Я бы предложил использовать сопрограммы kotlin и viewModel с LiveData, чтобы получить максимум от вашей ситуации. Rx имеет кривую обучения, хотя он предлагает сотни операторов для всех видов операций. Если вы действительно хотите изучить способ kotlin, посмотрите на kotlin потоки и каналы.

Если бы я был на вашем месте, я бы решил свою проблему с ViewModels, LiveData и сопрограммами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...