Android
2021-02-02
Kiedy zaczynałem poznawać Androida jakoś w 2014 roku i zbierać pierwsze programistyczne szlify nie zastanawiałem się zbytnio nad architekturą 😪
Wiele było przecież przykładów, gdzie logika widoku i danych były wymieszane i splątane w metody cyklu życia aplikacji w jednym Activity.
Aktywności takie często były koszmarem 😟, który nie sposób było przetestować ani w żaden sposób sensownie utrzymywać. Nastała potrzeba wprowadzenia architektury...
Znane z innych technologii rozdzielenie dostępu do danych od widoku stało się główną ideą dla zaadaptowania MVP.
Tak też na blogu pojawiły się wpisy o MVP, gdzie opisuję przykładowy projekt:
MVP w Androidzie
Już wtedy pojawił się zalążek pomysłu, żeby aplikacja była zorientowana na fragmenty. Jak wiemy później Google przyjęło ten koncept jako Navigation Component:
Navigation Component
Ostatecznie skończyliśmy z oficjalnym rozwiązaniem od Google, gdzie rolę presentera przejął nowy twór czyli ViewModel👏.
I tak chciałbym zakończyć ten akapit, jednak los chciał, że miałem ostatnio przyjemność pracować w projekcie, gdzie zostało wykorzystane MVP...
Na początku podszedłem to tego optymistycznie, gdyż projekt wydawał się prosty i idealny pod MVP. Po czasie jednak wyniknęły pewne problemy, o których chcę tutaj opowiedzieć. A raczej ich rozwiązaniach 🤓
TL;DR MVP było dobre do czasu, ale zostańmy z MVVM.
Domyślnie przy użyciu Navigation Component, fragmenty podczas nawigacji nie utrzymują swoich stanów. W większości przypadków jest to zachowanie oczekiwane, jednak są przypadki, dla których warto zrobić wyjątek.
W takim przypadku warto skorzystać z SavedStateHandle:
Saved State module for ViewModel
Jak można zobaczyć w dokumentacji, kiedy korzystamy z ViewModelu to implementacja tego rozwiązania jest skrojona na miarę 👌
Sytuacje, kiedy może przydać się zapamiętywanie stanu widoku to:
1. Zachowanie pozycji przesunięcia listy
2. Optymalizacja liczby zapytań o dane
3. Przechowanie ustawienia filtrów i sortowania
4. Ograniczenie akcji obciążających CPU (np. ładowanie Bitmap)
Tak jak powyższa funkcjonalność przy niektórych aplikacjach może się nie przydać, tak praktycznie nie można wyeliminować komunikacji pomiędzy fragmentami.
Na ten moment współdzielony ViewModel jest jedynym sensowym rozwiązaniem do zwracania rezultatu z jednego ekranu. Można tworzyć obejścia np. na LiveData z nawigacji... ale nie jest to zbyt eleganckie rozwiązanie🤔.
Shared ViewModel
Kiedy MVVM zostało ogłoszone jako oficjalna architektura dla Androida Google poniekąd wskazało na jakich komponentach będzie tworzyć pomocne biblioteki.
Jednym z takich przykładów jest biblioteka do stronicowania. W przykładach pokazane jest jak używać tego z ViewModel'em oraz LiveData. Po co mielibyśmy wymyślać koło na nowo?😶
Paging library
Dzięki ViewModelFactory możemy regulować w jaki sposób dostarczany jest ViewModel do widoku.
Stworzenie testowej fabryki dla testowego wariantu aplikacji np. TestAppComponent w daggerze pozwoli na mockowanie metod i pól w ViewModelu.
Działanie takie pomaga przy testowaniu UI oraz integracyjnym naszego projektu. 🚧
Przykład testowej fabryki
Jak widać na szybko można przedstawić 3 lub 4 argumenty za MVVM, co więcej nie tylko obrót ekranu powoduje przeładowanie Activity / Fragment.
Zmiana rozmiaru widoku, Picture in Picture, zmiana dark / light mode. W każdej z tych sytuacji warto by przetrwać zmiany cyklu życia.😀
Dziękuję Ci za przeczytanie tego materiału 😀 Jeżeli spodobało Ci się to o czym piszę, możesz sprawdzić więcej materiałów na blogu lub udostępnić znajomym. Będzie mi bardzo miło 😊
Jestem młodym programistą, który dumnie dzierży wiele pasji takich jak bieganie czy piwowarstwo domowe. Jedną z nich jest także programowanie i o tym właśnie zamierzam tutaj pisać.
Zachęcam Cię do odwiedzenia mojej strony na Google Play store i sprawdzenia wszystkich moich aplikacji.