AndroidViewModel vs ViewModel

158

Wraz z wprowadzeniem biblioteki składników architektury systemu Android wprowadzono kilka nowych klas, w tym AndroidViewModeli ViewModel. Jednak mam problem ze zrozumieniem różnicy między tymi dwiema klasami. PlikDokumentacja zwięźle opisuje AndroidViewModelnastępująco:

Świadomość kontekstu aplikacji ViewModel

Doceniam zwięzłość, ale co to dokładnie oznacza? Kiedy powinniśmy zdecydować się na stosowanie AndroidViewModelprzez ViewModeli vice versa?

cascal
źródło

Odpowiedzi:

223

AndroidViewModel zapewnia kontekst aplikacji

Jeśli potrzebujesz użyć kontekstu wewnątrz swojego Viewmodel, powinieneś użyć AndroidViewModel (AVM), ponieważ zawiera on kontekst aplikacji. Aby pobrać wywołanie kontekstu getApplication(), w przeciwnym razie użyj zwykłego ViewModel (VM).

AndroidViewModel ma kontekst aplikacji . Wszyscy wiemy , że posiadanie statycznej instancji kontekstu jest złe, ponieważ może powodować wycieki pamięci !! Jednak posiadanie statycznej instancji aplikacji nie jest tak złe, jak mogłoby się wydawać, ponieważ w uruchomionej aplikacji jest tylko jedna instancja aplikacji.

Dlatego używanie i posiadanie wystąpienia aplikacji w określonej klasie nie stanowi ogólnie problemu. Jeśli jednak instancja aplikacji odwołuje się do nich, jest to problem z powodu problemu z cyklem odniesienia.

Zobacz także informacje o wystąpieniu aplikacji

AndroidViewModel problematyczny dla testów jednostkowych

AVM zapewnia kontekst aplikacji, który jest problematyczny w przypadku testów jednostkowych. Testy jednostkowe nie powinny zajmować się żadnym cyklem życia systemu Android, takim jak kontekst.

Alex
źródło
40
Dlaczego więc nie zawsze używać AndroidViewModel? możesz później potrzebować kontekstu, nawet jeśli nie potrzebujesz go teraz. Czy jest w tym jakiś minus?
T. Rex
19
@ T.Rex Jeśli spojrzysz na kod, rozszerza ViewModelsię on tylko o pole wskazujące na Application. Jeśli go nie potrzebuję, nie lubię mieć obowiązkowego konstruktora z Applicationparametrem (który AndroidViewModelwymaga) i raczej po prostu używam ViewModel. Kiedy potrzebuję kontekstu w przyszłości, mogę go łatwo zmienić.
Boy
3
Użyj, ViewModelgdy chcesz go używać z fragmentem lub do udostępniania ViewModelmiędzy różnymi fragmentami tego samego działania.
codelearner
22
@ T.Rex nie użyłby AndroidViewModel- będąc Contextzależnym - uniemożliwiłby przetestowanie go w zwykłym teście jednostkowym, pozostawiając tylko testy oprzyrządowania jako możliwość? Sam się tym nie bawiłem (jeszcze), to tylko myśl
Konrad Morawski
2
AndroidViewModel i ViewModel są takie same, jedyną różnicą jest to, że AndroidViewModel zawiera kontekst aplikacji. Możesz użyć ViewModel i przekazać kontekst do ViewModel, aby działał, który ładuje dane z MediaStore, lub użyj AndroidViewModel z kontekstem aplikacji.
Alex,
9

Wreszcie mam coś prostszego wyjaśnienia, trochę ...... ... Klasa AndroidViewModel jest podklasą ViewModel i podobnie do nich, są przeznaczone do przechowywania i zarządzania danymi związanymi z interfejsem użytkownika, są odpowiedzialne za przygotowanie i dostarczenie danych dla interfejsu użytkownika i automatycznie zezwalaj na przetrwanie zmian konfiguracji.

Jedyną różnicą w przypadku AndroidViewModel jest to, że zawiera kontekst aplikacji, co jest przydatne, jeśli potrzebujesz kontekstu do uzyskania usługi systemowej lub masz podobne wymagania. pogrubiony tekst sprawia, że ​​lepiej go wyczuć.

user9830926
źródło
1
oficjalne źródło medium.com/androiddevelopers/…
Neeraj Sewani
4

AndroidViewModel jest podklasą ViewModel . Różnica między nimi polega na tym, że możemy przekazać kontekst aplikacji, który może być używany zawsze, gdy kontekst aplikacji jest wymagany, na przykład do utworzenia wystąpienia bazy danych w repozytorium.

AndroidViewModel to ViewModel uwzględniający kontekst aplikacji.

AndroidViewModel:

public class PriceViewModel extends AndroidViewModel {
private PriceRepository priceRepository;

public PriceViewModel(@NonNull Application application) {
    super(application);
    priceRepository= new PriceRepository(application);
    allPrices = priceRepository.getAllPrices();
}

ViewModel:

public class PriceViewModel extends ViewModel {
public PriceViewModel() {
    super();
}

Należy używać AndroidViewModel tylko wtedy, gdy potrzebujesz kontekstu aplikacji.

Nigdy nie należy przechowywać odniesienia do działania ani widoku, który odwołuje się do działania w ViewModel, ponieważ ViewModel jest zaprojektowany tak, aby przeżył działanie i spowoduje wyciek pamięci.

Jan
źródło