В чем разница между методами map() и switchMap ()?
в чем разница между этими 2 методами класса LiveData? Официальный документ и учебник довольно расплывчаты по этому поводу. В map () Метод первый параметр называется источник а в switchMap() это называется триггер. В чем причина этого?
3 ответов
согласно документации
применяет функцию к значению, хранящемуся в объекте LiveData, и распространяет результат вниз по потоку.
подобно map, применяет функцию к значению, хранящемуся в объекте LiveData, и разворачивает и отправляет результат вниз по потоку. функция передана switchMap() должен возвращать объект LiveData.
другими словами, Я не могу быть на 100% прав, но если вы знакомы с RxJava;Transformations#map
вроде как Observable#map
& Transformations#switchMap
похож на Observable#flatMap
.
давайте возьмем пример, есть LiveData, который испускает строку, и мы хотим отобразить эту строку заглавными буквами.
один подход будет следующим: в деятельности или фрагменте
Transformations.map(stringsLiveData, String::toUpperCase)
.observe(this, textView::setText);
функции перешел в map
возвращает только строку, но это Transformation#map
что в конечном итоге возвращает LiveData
.
второй подход; в деятельности или фрагмент
Transformations.switchMap(stringsLiveData, this::getUpperCaseStringLiveData)
.observe(this, textView::setText);
private LiveData<String> getUpperCaseStringLiveData(String str) {
MutableLiveData<String> liveData = new MutableLiveData<>();
liveData.setValue(str.toUpperCase());
return liveData;
}
если вы видите Transformations#switchMap
фактически подменил LiveData
. Итак, опять же согласно документации функция, переданная switchMap (), должна возвращать объект LiveData.
Итак, в случае map
это источник LiveData
вы трансформируетесь и в случае switchMap
шли LiveData
будет действовать как триггер на котором он переключится на другой LiveData
после разворачивания и отправки результата вниз по течению.
мое наблюдение заключается в том, что если ваш процесс преобразования быстрый (не включает работу с базой данных или сетевую активность), то вы можете использовать map
.
однако, если ваш процесс преобразования медленный (включая работу с базой данных или сетевую активность), вам нужно использовать switchMap
switchMap
используется при выполнении трудоемкой операцией
class MyViewModel extends ViewModel {
final MutableLiveData<String> mString = new MutableLiveData<>();
final LiveData<Integer> mCode;
public MyViewModel(String string) {
mCode = Transformations.switchMap(mString, input -> {
final MutableLiveData<Integer> result = new MutableLiveData<>();
new Thread(new Runnable() {
@Override
public void run() {
// Pretend we are busy
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int code = 0;
for (int i=0; i<input.length(); i++) {
code = code + (int)input.charAt(i);
}
result.postValue(code);
}
}).start();
return result;
});
if (string != null) {
mString.setValue(string);
}
}
public LiveData<Integer> getCode() {
return mCode;
}
public void search(String string) {
mString.setValue(string);
}
}
map
не подходит для трудоемкой операцией
class MyViewModel extends ViewModel {
final MutableLiveData<String> mString = new MutableLiveData<>();
final LiveData<Integer> mCode;
public MyViewModel(String string) {
mCode = Transformations.map(mString, input -> {
/*
Note: You can't launch a Thread, or sleep right here.
If you do so, the APP will crash with ANR.
*/
/*
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
*/
int code = 0;
for (int i=0; i<input.length(); i++) {
code = code + (int)input.charAt(i);
}
return code;
});
if (string != null) {
mString.setValue(string);
}
}
public LiveData<Integer> getCode() {
return mCode;
}
public void search(String string) {
mString.setValue(string);
}
}
Map () концептуально идентичен использованию в RXJava, в основном вы меняете параметр LiveData в другом
SwitchMap() вместо этого вы собираетесь заменить LiveData сам с другим! Типичный случай, когда вы получаете некоторые данные из репозитория, например, и "устранить" предыдущую LiveData (для сбора мусора, чтобы сделать его более эффективным память обычно), вы передаете new LiveData, которые выполняют одно и то же действие( например, получение запроса)