Методы расширения Java для LiveData

#java #android #kotlin #android-livedata

#java #Android #kotlin #android-livedata

Вопрос:

В Kotlin есть метод расширения observeOnce (https://code.luasoftware.com/tutorials/android/android-livedata-observe-once-only-kotlin /) это поведение, которое я хочу воспроизвести в Java. Насколько я понял из поиска в Google, вы не можете использовать методы расширения Kotlin в java (возможно, это неправильно), поэтому у меня есть два варианта использования SingleEventLiveData, которые я реализовал и которые мне не нравятся, и удаление моего observer после использования;

 final LiveData<List<String>> stringsLiveData = mViewModel.getStrings();

stringsliveData.observe(getViewLifecycleOwner(), strings -> {
    // Do stuff with data here
    stringsLiveData.removeObservers(getViewLifecycleOwner());
});
  

Существует ли эквивалентный метод, который можно использовать в качестве ссылки выше, чтобы;

 mViewModel.getStrings().observeOnce(getViewLifecycleOwner(), strings -> {
    //Do stuff here
});
  

Редактировать: Согласно принятому ответу ниже (изменено для компиляции) У меня есть;

 class LiveDataUtils {
    public static <T> void observeOnce(LiveData<T> liveData, Observer<T> observer) {
        liveData.observeForever(o -> {
            liveData.removeObserver(observer);
            observer.onChanged(o);
        });
    }
}
  

и простое использование этого;

 LiveDataUtils.observeOnce(
    mViewModel.getStrings(),
    strings -> {
        // Do some work here
    }
);
  

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

1. Вы можете использовать методы расширения из Java. Это просто статические методы с первым параметром, являющимся получателем. Я не уверен, ограничили ли они это как-то в случае с данными в реальном времени, но, возможно, стоит попробовать

2. Да, я поиграл с этим, но, к сожалению, не могу заставить что-либо работать так, как я хочу.

3. Вы не должны удалять ВСЕХ наблюдателей, вы должны удалить только тот, observer который вы указали методом.

4. @EpicPandaForce обновлено, чтобы удалить только отдельного наблюдателя, что вы думаете о observe (владелец, o) против observeForever (o)

5. Что это зависит от того, что вы делаете. Хотя предполагаемый способ выполнения действий заключается в том, чтобы получать события только после onStart и до onStop . Я использовал observeForever внутри ViewModel, но я должен был использовать Transformations.switchMap (который внутренне использует observeForever / removeObserver).

Ответ №1:

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

Создайте класс util со статическим методом:

 public class LiveDataUtils {

public static <T> void observeOnce(LiveData<T> liveData, Observer<T> observer) {
    liveData.observeForever(new Observer<T>() {
        @Override
        public void onChanged(T t) {
            liveData.removeObserver(this);
            observer.onChanged(t);
        }
    });
   }
}
  

Я не тестировал код, поэтому в нем могут быть некоторые ошибки. Смысл был в том, чтобы показать вам, как вы можете заменить функции расширения в Java.

РЕДАКТИРОВАТЬ: Обновлено в соответствии с последующими действиями @Marek Potkan, поскольку это принятый ответ. Как я уже упоминал, я не тестировал код и по ошибке предоставил неверную ссылку.

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

1. Я бы рекомендовал переместить removeObserver выше observer.onChange , так как вы могли бы получить другой элемент через LiveData, прежде чем удалять его.

2. Я немного изменил этот код, чтобы он мог компилироваться, и он работает просто отлично, спасибо! Я отредактирую свой ответ, чтобы показать правильный код.

3. @Ge3ng имеет правильную точку зрения, вы можете переключиться, чтобы избежать получения нескольких элементов. Рад, что смог помочь, всегда пожалуйста 🙂

Ответ №2:

ответ @deluxe1 не сработал бы. observer Вызывается observer удаление, но это не тот, который используется в observeForever методе. Вместо лямбда-функции здесь следует использовать расширенную версию:

 public static <T> void observeOnce(LiveData<T> liveData, Observer<T> observer) {
    liveData.observeForever(new Observer<T>() {
        @Override
        public void onChanged(T t) {
            liveData.removeObserver(this);
            observer.onChanged(t);
        }
    });
}
  

Я протестировал оба подхода.