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?
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.
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.
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ć.
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.
ViewModel
się on tylko o pole wskazujące na Application. Jeśli go nie potrzebuję, nie lubię mieć obowiązkowego konstruktora zApplication
parametrem (któryAndroidViewModel
wymaga) i raczej po prostu używamViewModel
. Kiedy potrzebuję kontekstu w przyszłości, mogę go łatwo zmienić.ViewModel
gdy chcesz go używać z fragmentem lub do udostępnianiaViewModel
między różnymi fragmentami tego samego działania.AndroidViewModel
- będącContext
zależ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ślWreszcie 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ć.
źródło
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:
ViewModel:
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.
źródło