Dynamiczne moduły w Androidzie - #2 - Dagger i wstrzykiwanie zależności

14.11.2019 | Adam Nowicki

Wstęp

W poprzedniej części artykułu pobraliśmy tekst z dynamicznego modułu.

Naszym celem jest osiągniecie czegoś więcej, dlatego w dzisiejszym artykule pokaże Wam Fragment z dynamicznego modułu, używając do tego Daggera. Dagger2 to biblioteka do dependency injection dla Androida. Dodamy do naszego głównego modułu Fragment ViewModel i spróbujemy go zaprezentować na ekranie. Dziś przygotujemy projekt tak, by w przyszłości łatwiej przenieść ten kod do naszego dynamicznego feature.

Konfiguracja

Aby używać daggera dodajmy do naszego build.gradle w module app następujące zależności:

oraz w build.gradle modułu feature:

Dla obu powyższych na górze pliku musimy dopisać:

Dla oddzielenia logiki od widoku użyjemy wzorca MVVM. Z tego powodu musimy dodać jeszcze:

Nowa funkcjonalność

Dodajmy klasy potrzebne do pokazania naszego fragmentu. Wszystko w module app.

oraz interface i jego implementacje dla zasilania danymi:

Wszystkie rzeczy dotyczące daggera dependency injection będziemy trzymać w pakiecie dagger. Zaczniemy od komponentu, gdzie dodamy zależność do kilku modułów:

Pierwszy to moduł AndroidSupportInjection pozwalający na "automatyczne" wstrzykiwanie do activity fragmentu. W połączeniu z DaggerFragment, po którym dziedziczy nasz CoreFragment możemy od razu wstrzykiwać do naszego fragmentu.

DaggerFragment implementuje interfejs HasAndroidInjector i w metodzie androidInjector zwraca obiekt wstrzykniętego DispatchingAndroidInjector. Sam mechanizm wstrzykiwania działa dzięki przeciążeniu metody onAttach i wywołaniu:

AndroidSupportInjection.inject(this);

Drugi moduł pozwala na dostęp do kontekstu i implementacji AppRepository:

Kolejne moduły pozwalają na komunikację między fragmentem a viewModel:

Brakuje nam jeszcze klasy MainViewModel, który będzie używany w MainActivity:

Mamy już wszystko czego potrzebujemy, teraz trzeba tylko zaktualizować widok głównego activity. Dodajmy więc w pliku activity_main.xml przycisk pokazujący fragment i kontener dla tego fragmentu.

W mainActivity na poczatek wstrzykujemy AppRepository:

Nie dziedziczymy tutaj po DaggerActivity, więc w onCreate trzeba wywołać:

AndroidInjection.inject(this)

Dodatkowo należy zaimplementować interfejs HasSupportFragmentInjector oraz jego metodę:

override fun supportFragmentInjector(): AndroidInjector<Fragment> {
    return (application as MyApplication).supportFragmentInjector()
}

Teraz już możemy na naszym textView pokazać tekst z AppRepositoryImpl:

textView.text = repo.getData()

Po kliknieciu przycisku załadujemy do stworzonego wcześniej kontenera widok naszego CoreFragment:

Tworzymy go za pomocą refleksji żeby łatwo było zaraz przejść na ładowanie fragmentu z dynamicznego modułu. Po uruchomieniu projektu i kliknięciu przycisku zobaczymy następujący ekran:

Podsumowanie

W tej części artykułu skupiliśmy się na daggerze i jego konfiguracji. W przykładowej aplikacji mamy button pokazujący fragment z głównego modułu aplikacji. Do fragmentu da się wstrzykiwać zależności. Mamy dostęp w ViewModelu, a w ViewModelu do Repository. Dla początkujących programistów nie wszystko jest łatwe i oczywiste. W razie problemów zachęcam do przejrzenia dokumentacji lub przerobienia kilku tutoriali.

W kolejnej części zamiast pokazywania fragmentu z głownego modułu, pokażemy fragment z modułu dynamicznego.

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

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