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ć liveLocation
obserwowalne, 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
. RxJava
zapewnia więcej możliwości transformacji (jak wspomniano w @Bob Dalgleish).
Obecnie używamy RxJava
w ź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
, LiveDataReactiveStreams
robi 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 RxJava
mó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 LiveData
wię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 LiveData
nie jest to porównywalne RxJava
pod względem możliwości i mocy, jaką daje programistom, reaktywnego programowania i RxJava
jest trudnym do zrozumienia pojęciem i narzędziem dla wielu. Z drugiej strony, nie sądzę, że LiveData
ma 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
LiveData
miałby się onStop
faktycznie 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 LiveData
jako obserwowalny, który pozwala zarządzać obserwatorami będącymi w active
stanie. Innymi słowy LiveData
jest 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 OnCreate
metodzie 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 LiveData
jest stosowany z komponentami architektury Lifecycle
i ViewModel
(jak widzieliśmy) często . W rzeczywistości w LiveData
połą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ć LiveData
zaleca 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ć LiveData
w realnych sytuacjach życiowych. Tutaj możesz znaleźć kilka przykładów użycia z wielkiego wspólnego oprogramowania .
Omotać zasadzieLiveData
jest 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, żeRXJava
moż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
LiveData
jako rzecz posiadacza danych i nic więcej. Możemy również powiedzieć, że LiveData jest konsumentem świadomym cyklu życia. LiveData
zaleca 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.