Dynamiczne moduły w Androidzie - #3 - wstrzykiwanie modułów

05.12.2019 | Adam Nowicki

Wstęp

Po wykonaniu kroków z poprzedniego artykułu mamy aplikację pokazującą fragment z głównego modułu aplikacji.

To czas, by połączyć siły i wstrzyknąć z wykorzystaniem Daggera nasz dynamiczny moduł. W tej części artykułu również pokażemy fragment, nawet bardzo podobnie wyglądający, ale zaimplementujemy go w dynamicznym module. Część kodu będzie podobna do tego z kroku drugiego, pozostała część to obejścia do osiągnięcia naszego celu czyli wstrzykiwania do modułu feature. Zaczynajmy!

Ładowanie fragmentu

Do aktywności w module app załadujemy fragment z dynamicznego modułu. W tym celu musimy trochę "pokombinować".

Najpierw oczywiście tworzymy Fragment ViewModel:

oraz moduł daggera:

Żeby zapewnić działanie automatycznego wstrzykiwania zależności musimy zrobić kilka zmian w głównej klasie aplikacji (MyApplication).

Stworzymy sobie interfejs FeatureModule:

oraz obiekt opisujący nasz dynamiczny moduł i  implementujący ten interfejs:

MyApplication dodamy pole przechowujące zbiór wstrzykniętych modułów:

Zmieniamy supportFragmentInjector oraz activityInjector i zwracamy teraz "nasze" obiekty.

Od teraz activityInjector fragmentInjector wstrzykną zależności do wszystkich znanych im activity i fragmentów.

Nowa funkcjonalność

Teraz musimy tylko wskazać w kodzie gdzie chcemy wstrzykiwać. Napiszemy do tego specjalną metodę, która będzie wywoływana przed przejściem do dynamicznego fragmentu:

Ostatnią potrzebną rzeczą w module app jest kolejny interfejs:

Przechodzimy do modułu feature. Tworzymy tam klasę implementującą powyższy interfejs.

Wypada jeszcze stworzyć komponent dla modułu:

W zależnościach podajemy nasz główny komponent. Niestandardowa jest metoda inject. Jest ona nam potrzebna, żeby wstrzykiwać do klasy FeatureInjector. Ostatnią rzeczą jest daggerowy scope. Musi być inny niż scope całej aplikacji. Tworzymy więc odpowiednią adnotację:

Żeby użyć tego mechanizmu, który utworzyliśmy zmienimy w MainActivity metodę onModuleDownloaded:

Jak widać, jedyną różnicą w stosunku do onClickListener button_fragment_core jest to, że dodajemy moduleInjector naszego dynamicznego modułu. Dzięki temu działa magia wstrzykiwania zależności do feature.


Podsumowanie

Podsumowując: po kliknięciu przycisku dociągamy dynamiczny moduł i prezentujemy zdefiniowany w nim fragment. Wszystko oparte jest o bibliotekę Dagger. Problemem w standardowym użyciu daggera jest to, że główny moduł aplikacji nie wie o istnieniu modułu dynamicznego. Mamy do tego gotowe obejście, dynamiczny moduł rejestruje się w głównej klasie aplikacji i dzięki temu możemy stworzyć odpowiedni komponent.

Kod z dziś w całości dostępny tutaj:

https://github.com/adamnovicki/TechBlog/tree/step3