Nie dostaję powodu, by używać RxJava w Androidzie i LiveData z Android Architectural Components. Bardzo pomocne byłoby wyjaśnienie przypadków użycia i różnic między nimi oraz przykładowy przykład w postaci kodu, który wyjaśnia różnice między nimi.
Nie dostaję powodu, by używać RxJava w Androidzie i LiveData z Android Architectural Components. Bardzo pomocne byłoby wyjaśnienie przypadków użycia i różnic między nimi oraz przykładowy przykład w postaci kodu, który wyjaśnia różnice między nimi.
Odpowiedzi:
Android LiveData jest odmianą oryginalnego wzorca obserwatora, z dodatkiem aktywnych / nieaktywnych przejść. Jako taki ma bardzo restrykcyjny zakres.
Korzystając z przykładu opisanego w Android LiveData , tworzona jest klasa do monitorowania danych lokalizacji oraz rejestracji i wyrejestrowania na podstawie stanu aplikacji.
RxJava zapewnia operatory, które są znacznie bardziej uogólnione. Załóżmy, że to możliwe do zaobserwowania dostarczy danych o lokalizacji:
Observable<LocationData> locationObservable;
Implementację obserwowalnego można zbudować za pomocą Observable.create()mapowania operacji oddzwaniania. Po subskrybowaniu obserwowalnego, połączenie zwrotne jest rejestrowane, a gdy nie jest subskrybowane, połączenie zwrotne nie jest rejestrowane. Implementacja wygląda bardzo podobnie do kodu podanego w przykładzie.
Załóżmy również, że masz obserwowalne, które emituje wartość true, gdy aplikacja jest aktywna:
Observable<Boolean> isActive;
Następnie możesz zapewnić wszystkie funkcje LiveData w następujący sposób
Observable<LocationData> liveLocation =
isActive
.switchMap( active -> active ? locationObservable : Observable.never() );
switchMap()Operator będzie albo zapewnić bieżącą lokalizację jako strumień lub nic, jeśli aplikacja nie jest aktywna. Gdy już będziesz mieć liveLocationobserwowalne, możesz zrobić z nim wiele rzeczy, używając operatorów RxJava. Mój ulubiony przykład to:
liveLocation.distinctUntilChanged()
.filter( location -> isLocationInAreaOfInterest( location ) )
.subscribe( location -> doSomethingWithNewLocation( location ) );
Spowoduje to wykonanie akcji tylko po zmianie lokalizacji, a lokalizacja jest interesująca. Możesz tworzyć podobne operacje, które łączą operatory czasu w celu określenia prędkości. Co ważniejsze, można zapewnić szczegółową kontrolę operacji wykonywanych w wątku głównym, wątku w tle lub wielu wątkach, używając operatorów RxJava.
Chodzi o to, że RxJava łączy kontrolę i synchronizację czasową w jednym wszechświecie, wykorzystując operacje z biblioteki, a nawet operacje niestandardowe, które udostępniasz.
LiveData dotyczy tylko jednej niewielkiej części tego wszechświata, co jest odpowiednikiem budowania liveLocation.
The point of RxJava is that it combines control and timing into a single universe, using operations provided from the library, or even custom operations that you provide. Ale cykl życia LiveData nie jest świadomy. Gdybyśmy mieli użyć Rx, czy nie musielibyśmy radzić sobie ze zmianami cyklu życia?
Jeśli chodzi o oryginalne pytanie, zarówno RxJava, jak i LiveData bardzo dobrze się uzupełniają.
LiveDataświeci na warstwie ViewModel, dzięki ścisłej integracji z cyklami życia Androida i ViewModel. RxJavazapewnia więcej możliwości transformacji (jak wspomniano w @Bob Dalgleish).
Obecnie używamy RxJavaw źródłach danych i warstwach repozytoriów, a przekształca się je LiveData(używa LiveDataReactiveStreams) w ViewModels (przed wystawieniem danych na działania / fragmenty) - całkiem zadowolony z tego podejścia.
observeOn, LiveDataReactiveStreamsrobi to mimo to dzwoniąc LiveData.postValue(). I nie ma gwarancji subscribeOn, że ogólnie będziesz mieć jakikolwiek efekt.
Istnieje wiele różnic między LiveData i RxJava:
public class RegistrationViewModel extends ViewModel {
Disposable disposable;
private RegistrationRepo registrationRepo;
private MutableLiveData<RegistrationResponse> modelMutableLiveData =
new MutableLiveData<>();
public RegistrationViewModel() {
}
public RegistrationViewModel(RegistrationRepo registrationRepo) {
this.registrationRepo = registrationRepo;
}
public void init(RegistrationModel registrationModel) {
disposable = registrationRepo.loginForUser(registrationModel)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Response<RegistrationResponse>>() {
@Override
public void accept(Response<RegistrationResponse>
registrationModelResponse) throws Exception {
modelMutableLiveData.setValue(registrationModelResponse.body());
}
});
}
public LiveData<RegistrationResponse> getModelLiveData() {
return modelMutableLiveData;
}
@Override
protected void onCleared() {
super.onCleared();
disposable.dispose();
}
}
onCleared.
W rzeczywistości, LiveData nie jest zasadniczo różne narzędziem RxJava, więc dlaczego został wprowadzony jako składnik architektury kiedy RxJavamógł łatwo zarządzać cyklem przechowując wszystkie subskrypcje obserwabli w CompositeDispoable obiekcie, a następnie usuwania ich onDestroy() z Activity lub onDestroyView() z Fragment użyciem tylko jednego wiersz kodu?
Odpowiedziałem na to pytanie w pełni, budując aplikację do wyszukiwania filmów raz, używając RxJava, a następnie używając LiveData tutaj .
Krótko mówiąc, tak, może, ale wymagałoby to najpierw zastąpienia odpowiednich metod cyklu życia, oprócz posiadania podstawowej wiedzy o cyklu życia. Dla niektórych może to nadal nie mieć sensu, ale faktem jest, że według jednej z sesji Jetpack w Google I / O 2018 wielu programistów uważa kompleks zarządzania cyklem życia. Błędy awaryjne wynikające z braku obsługi zależności cyklu życia mogą być kolejnym znakiem, że niektórzy programiści, nawet jeśli znają się na cyklu życia, zapominają o tym zadbać w każdym działaniu / fragmencie używanym w swojej aplikacji. W dużych aplikacjach może to stanowić problem, pomimo negatywnego wpływu na produktywność.
Najważniejsze jest to, że po wprowadzeniu oczekuje się, że LiveDatawiększa liczba programistów przyjmie MVVM bez konieczności rozumienia zarządzania cyklem życia, wycieku pamięci i awarii. Mimo że nie mam wątpliwości, że LiveDatanie jest to porównywalne RxJavapod względem możliwości i mocy, jaką daje programistom, reaktywnego programowania i RxJavajest trudnym do zrozumienia pojęciem i narzędziem dla wielu. Z drugiej strony, nie sądzę, że LiveDatama być zamiennikiem RxJava- po prostu nie może - ale bardzo prostym narzędziem do obsługi kontrowersyjnego, szeroko rozpowszechnionego problemu, którego doświadcza wielu programistów.
** AKTUALIZACJA ** Dodałem tutaj nowy artykuł , w którym wyjaśniłem, w jaki sposób niewłaściwe użycie LiveData może prowadzić do nieoczekiwanych rezultatów. RxJava może przyjść na ratunek w takich sytuacjach
LiveDatamiałby się onStopfaktycznie pozbyć
Jak zapewne wiesz w reaktywnym ekosystemie, mamy obserwowalny, który emituje dane i obserwatora, który subskrybuje (otrzyma powiadomienie) o tej obserwowalnej emisji, nic dziwnego, jak działa tak zwany wzorzec obserwatora. Obserwowalne coś „krzyczy”, Obserwator zostaje powiadomiony, że Obserwowalny coś krzyczy w danym momencie.
Myśl LiveDatajako obserwowalny, który pozwala zarządzać obserwatorami będącymi w activestanie. Innymi słowy LiveDatajest prosty do zaobserwowania, ale także dba o cykl życia.
Ale zobaczmy dwa przypadki kodu, o które prosisz:
A) Dane na żywo
B) RXJava
A) Jest to podstawowa implementacja LiveData
1) zazwyczaj tworzysz LiveData w ViewModel, aby zachować zmianę orientacji (możesz mieć LiveData tylko do odczytu lub MutableLiveData, który jest zapisywalny, więc zwykle eksponujesz poza klasą LiveData)
2) w OnCreatemetodzie Main Activity (nie ViewModel) „subskrybujesz” obiekt Observer (zwykle metoda onChanged)
3) uruchomisz metodę obserwuj, aby ustanowić link
Po pierwsze ViewModel(posiada logikę biznesową)
class ViewModel : ViewModel() { //Point 1
var liveData: MutableLiveData<Int> = MutableLiveData()
}
I to jest MainActivity(tak głupie, jak to możliwe)
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val ViewModelProvider= ViewModelProviders.of(this).get(ViewModel::class.java)
ViewModelProvider.observe(this, Observer {//Points 2 and 3
//what you want to observe
})
}
}
}
B) To jest podstawowa implementacja RXJava
1) oświadczasz, że jest obserwowalny
2) deklarujesz obserwatora
3) subskrybujesz Obserwowalny wraz z Obserwatorem
Observable.just(1, 2, 3, 4, 5, 6) // Point 1
.subscribe(new Subscriber() { //Points 2 & 3
@Override
public void onCompleted() {
System.out.println("Complete!");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Double value) {
System.out.println("onNext: " + value);
}
});
W szczególności LiveDatajest stosowany z komponentami architektury Lifecyclei ViewModel(jak widzieliśmy) często . W rzeczywistości w LiveDatapołączeniu z ViewModel pozwala na bieżąco aktualizować każdą zmianę w Observerie, dzięki czemu wydarzenia są zarządzane w czasie rzeczywistym tam, gdzie jest to potrzebne. Aby korzystać LiveDatazaleca się poznać koncepcję cyklu życia i względne obiekty LifeCycleOwner / Lifecycle , również chciałbym zaproponować Ci spojrzeć na przekształceniach , jeśli chcesz wprowadzić LiveDataw realnych sytuacjach życiowych. Tutaj możesz znaleźć kilka przykładów użycia z wielkiego wspólnego oprogramowania .
Omotać zasadzieLiveDatajest uproszczonaRXJava, elegancki sposób, aby obserwować zmiany w wielu komponentów bez tworzenia jawnych tzw zasady zależnościami pomiędzy komponentami, dzięki czemu można przetestować wiele łatwiej kod i sprawiają, że o wiele bardziej czytelny. RXJava, pozwala robić rzeczy LiveData i wiele więcej. Ze względu na rozszerzone funkcjonalności RXJava, możesz zarówno używać LiveData do prostych przypadków, jak i wykorzystywać całą moc RXJava, używając komponentów architektury Android jako ViewModel , oczywiście oznacza to, żeRXJavamoże być o wiele bardziej skomplikowane, po prostu pomyśl o setkach operatorów SwitchMap i Map LiveData (w tej chwili).
RXJava wersja 2 to biblioteka, która zrewolucjonizowała paradygmat obiektowy, dodając tak zwany funkcjonalny sposób zarządzania przepływem programu.
LiveData to podzbiór komponentów architektury Androida opracowany przez zespół Androida.
W przypadku danych na żywo i innych komponentów architektury, wycieki pamięci i inne podobne problemy są obsługiwane przez komponenty architektury. Ponieważ został opracowany przez zespół Androida, jest najlepszy dla Androida. Zapewniają także aktualizacje obsługujące nowe wersje Androida.
Jeśli chcesz używać tylko do tworzenia aplikacji na Androida, wybierz komponenty architektury Androida. W przeciwnym razie, jeśli chcesz użyć innej aplikacji Java, takiej jak aplikacja internetowa, aplikacje komputerowe itp., Użyj RxJava
LiveDatajako rzecz posiadacza danych i nic więcej. Możemy również powiedzieć, że LiveData jest konsumentem świadomym cyklu życia. LiveDatazaleca się znajomość koncepcji cyklu życia i względnych obiektów LifeCycleOwner / LifeCycle, aby uzyskać możliwości transformacji i przesyłania strumieniowego dla logiki biznesowej i operacji uwzględniających cykl życia dla interfejsu użytkownika.
Rx to potężne narzędzie, które umożliwia rozwiązanie problemu w eleganckim stylu deklaratywnym. Obsługuje opcje biznesowe lub operacje interfejsu API usługi
Porównując LiveData do RxJava porównuje jabłka z sałatkami owocowymi.
Porównaj LiveData do ContentObserver i porównujesz jabłka z jabłkami. LiveData skutecznie zastępuje ContentObserver z uwzględnieniem cyklu życia.
Porównywanie RxJava do AsyncTask lub dowolnego innego narzędzia do gwintowania to porównywanie sałatek owocowych z pomarańczami, ponieważ RxJava pomaga w czymś więcej niż tylko wątkowaniu.