Dagger 2 per sviluppatori Android inesperti. Pugnale 2. Livello avanzato. Parte 2
Questo articolo è la settima parte di una serie di articoli destinati, secondo l'autore, a coloro che non riescono a capire come gestire l' iniezione di dipendenza e il framework Dagger 2 , o semplicemente lo faranno. Scritto originariamente il 30 dicembre 2017. Traduzione gratis.

Questo è il settimo articolo della serie Dagger 2 per sviluppatori Android principianti. ... Se non hai letto i precedenti, allora sei qui .
Abbiamo anche esplorato tre nuove annotazioni. Creazione di diversi
Nell'articolo precedente, abbiamo creato dipendenze a livello di applicazione. Ma cosa succede se sono richieste solo le dipendenze di livello?
La soluzione migliore è creare moduli e componenti separati per oggetti con cicli di vita diversi.
Per spiegarlo, non voglio aggiungere nuovi oggetti al progetto discusso in precedenza. Invece, considera il nostro
Dai un'occhiata alla filiale Passaggio 1. Creare un'area di livello
Per le prossime modifiche, ho creato un pacchetto separato chiamato separate
Creiamo un nuovo ambito per Passaggio 2. Creazione di un componente per
Quindi, creiamo un componente separato (Componente) per
In questo esempio, al livello
Passaggio 3. Creazione di un modulo per
Ora creiamo un modulo che fornirà l'adattatore.
Attenzione all'annotazione
È inoltre necessario mappare questo modulo al componente corrispondente. Usiamo l'attributo
Passaggio 4. Creazione di una classe
Passaggio 5. Perfezionamento
Se crei il progetto, Dagger 2 genererà una classe per te Utilizzo dell'annotazione
Invece di dire a Dagger 2 di cosa hai bisogno
Modificando le classi come di seguito, possiamo iniziare a utilizzare l'annotazione Raffinatezza
Rimuoviamo i metodi Raffinatezza
Esattamente quello che serve! Il codice ora può essere eseguito.
Ora puoi continuare a esplorare ulteriormente Dagger 2, questa serie di articoli dovrebbe averti fornito una comprensione sufficiente di come funziona.

Questo è il settimo articolo della serie Dagger 2 per sviluppatori Android principianti. ... Se non hai letto i precedenti, allora sei qui .
Serie di articoli
- Dagger 2 per sviluppatori Android inesperti. Introduzione.
- Dagger 2 per sviluppatori Android inesperti. Iniezione di dipendenza. Parte 1 .
- Dagger 2 per sviluppatori Android inesperti. Iniezione di dipendenza. Parte 2 .
- Dagger 2 per sviluppatori Android inesperti. Pugnale 2.Parte 1 .
- Dagger 2 per sviluppatori Android inesperti. Pugnale 2.Parte 2 .
- Dagger 2 per sviluppatori Android inesperti. Pugnale 2. Livello avanzato.
Parte 1 . - Dagger 2 per sviluppatori Android inesperti. Pugnale 2. Livello avanzato.
Parte 2 (sei qui) .
All'inizio della serie
Abbiamo esaminato un progetto di esempio e abbiamo cercato di eliminare le relazioni forti con l'iniezione di dipendenza utilizzando Dagger 2 e annotazioni.Abbiamo anche esplorato tre nuove annotazioni.
@Scope
per creare oggetti in una singola istanza (singleton) .@Named
per separare i metodi che forniscono oggetti dello stesso tipo.@Qualifier
in alternativa@Named
... Creazione di diversiComponent
Nell'articolo precedente, abbiamo creato dipendenze a livello di applicazione. Ma cosa succede se sono richieste solo le dipendenze di livello?Activity
?Activity
viene creato e distrutto nel suo ciclo di vita, ma cosa succede alle dipendenze? Dipendenze create internamenteActivity
distrutto insieme aActivity
...La soluzione migliore è creare moduli e componenti separati per oggetti con cicli di vita diversi.
Per spiegarlo, non voglio aggiungere nuovi oggetti al progetto discusso in precedenza. Invece, considera il nostro
MainActivity
come oggetto separato e creare il nostro modulo e componente per esso.Dai un'occhiata alla filiale
Dagger2Part2
... Passaggio 1. Creare un'area di livelloActivity
Per le prossime modifiche, ho creato un pacchetto separato chiamato separateMainActivityFeature
...Creiamo un nuovo ambito per
MainActivity
...@Scope
public @interface MainActivityScope {}
Passaggio 2. Creazione di un componente perMainActivity
Quindi, creiamo un componente separato (Componente) perMainActivity
e contrassegnalo con l'annotazione appena creata.@Component(dependencies = RandomUserComponent.class)
@MainActivityScope
public interface MainActivityComponent {
RandomUserAdapter getRandomUserAdapter();
RandomUsersApi getRandomUserService();
}
Deve essere consentitoMainActivityComponent
in riferimento aRandomUserComponent
a cosa serve l'attributodependencies
... In altre parole, questo attributo dice a Dagger 2 di fare riferimento aRandomUserComponent
se sono necessarie dipendenze aggiuntive.In questo esempio, al livello
Activity
abbiamo bisogno di un adattatore per l'API e un oggetto a cui effettuare chiamateRandomUsersAPI
... Pertanto, implementiamo i metodigetRandomUserAdapter()
egetRandomUserService()
...
Passaggio 3. Creazione di un modulo perMainActivity
Ora creiamo un modulo che fornirà l'adattatore.@Module
public class MainActivityModule {
private final MainActivity mainActivity;
public MainActivityModule(MainActivity mainActivity) {
this.mainActivity = mainActivity;
}
@Provides
@MainActivityScope
public RandomUserAdapter randomUserAdapter(Picasso picasso){
return new RandomUserAdapter(mainActivity, picasso);
}
}
Nota: implementazioneMainActivity
tramite adattatore non è necessario, l'ho fatto ad esempio. Se hai bisogno di un contesto perPicasso
, quindi puoi usareholder.imageView.getContext()
...Attenzione all'annotazione
@MainActivityScope
che si aggiunge al metodorandomUserAdapter()
limitare la portata della dipendenza a un livelloActivity
...È inoltre necessario mappare questo modulo al componente corrispondente. Usiamo l'attributo
modules
... @Component(modules = MainActivityModule.class, dependencies = RandomUserComponent.class)
@MainActivityScope
public interface MainActivityComponent {
RandomUserAdapter getRandomUserAdapter();
RandomUsersApi getRandomUserService();
}

Passaggio 4. Creazione di una classeApplication
public class RandomUserApplication extends Application {
// add the name of this class to the manifest
private RandomUserComponent randomUserApplicationComponent;
public static RandomUserApplication get (Activity activity) {
return (RandomUserApplication) activity.getApplication ();
}
@Override
public void onCreate () {
super.onCreate ();
Timber.plant (new Timber.DebugTree ());
randomUserApplicationComponent = DaggerRandomUserComponent.builder ()
.contextModule (new ContextModule (this))
.build ();
}
public RandomUserComponent getRandomUserApplicationComponent () {
return randomUserApplicationComponent;
}
Questa classe eredita daApplication
, contiene tutte le dipendenze a livello di applicazione -RandomUserApplicationComponent
... Passaggio 5. PerfezionamentoMainActivity
Se crei il progetto, Dagger 2 genererà una classe per teDaggerMainActivityComponent
... Per usare le dipendenze di livelloActivity
avremo bisogno di ottenere alcune dipendenze a livello di applicazione.public class MainActivity extends AppCompatActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
....
MainActivityComponent mainActivityComponent = DaggerMainActivityComponent.builder()
.mainActivityModule(new MainActivityModule(this))
.randomUserComponent(RandomUserApplication.get(this).getRandomUserApplicationComponent())
.build();
randomUsersApi = mainActivityComponent.getRandomUserService();
mAdapter = mainActivityComponent.getRandomUserAdapter();
....
}
}
Nota: dai un'occhiata al metodoafterActivityLevelComponent()
in filiale con il progetto.Passaggio 6. Congratulazioni con te stesso
Abbiamo creato un codice abbastanza gestibile. Dipendenze di livello createActivity
... Congratulazioni con te stesso.Cosa succede se un componente ha 50 dipendenze?
Se ci sono davvero molte dipendenze, dobbiamo scrivere costantemente espressioni come quella qui sotto?randomUserApi = mainActivityComponent.getRandomUserService();
mAdapter = mainActivityComponent.getRandomUserAdapter();
…
Potresti decidere che questo non è importante per te, ma esiste una soluzione per questo problema. Utilizzo dell'annotazione@Inject
Invece di dire a Dagger 2 di cosa hai bisognoRandomUserService
eRandomUserAdapter
, lascia che Dagger 2 elabori il campo che contrassegniamo con l'annotazione@Inject
...Modificando le classi come di seguito, possiamo iniziare a utilizzare l'annotazione
@Inject
il prima possibile. Puoi vedere un esempio completo nel thread successivo . RaffinatezzaMainActivityComponent
Rimuoviamo i metodigetRandomUserService()
egetRandomUserAdapter()
e aggiungi un metodo per l'iniezioneMainActivity
...@Component(modules = MainActivityModule.class, dependencies = RandomUserComponent.class)
@MainActivityScope
public interface MainActivityComponent {
void injectMainActivity(MainActivity mainActivity);
}
RaffinatezzaMainActivity
public class MainActivity extends AppCompatActivity {
....
@Inject
RandomUsersApi randomUsersApi;
@Inject
RandomUserAdapter mAdapter;
....
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
.....
MainActivityComponent mainActivityComponent = DaggerMainActivityComponent.builder()
.mainActivityModule(new MainActivityModule(this))
.randomUserComponent(RandomUserApplication.get(this).getRandomUserApplicationComponent())
.build();
mainActivityComponent.injectMainActivity(this);
....
}
}
Come funziona? Quando Dagger 2 trova un metodo senza valore restituito (void
) capisce che deve esserci qualcosa di cui ha bisogno nella classe, cioè inizializzerà nella classe i campi contrassegnati con l'annotazione@Inject
...Esattamente quello che serve! Il codice ora può essere eseguito.
GIF

Sommario
Abbiamo esaminato un esempio di iniezione di dipendenza a livelloActivity
... Ho visto anche un esempio di utilizzo dell'annotazione@Inject
...Finalmente
Grazie per aver dedicato del tempo a leggere e supportare questa serie di articoli. Spero che tu abbia una certa comprensione delle dipendenze e di Dagger 2. Il motivo per cui ho scritto questa serie di articoli è perché ho migliorato la mia conoscenza di Dagger 2 leggendo molti articoli su vari blog, ma ho acquisito ancora più conoscenza durante la scrittura di questi articoli. voi. Pertanto, esorto tutti i lettori a condividere le loro conoscenze in ogni modo possibile. Non sono un esperto di Dagger 2, mi considero solo uno studente.Ora puoi continuare a esplorare ulteriormente Dagger 2, questa serie di articoli dovrebbe averti fornito una comprensione sufficiente di come funziona.
Collegamenti ad altre risorse (in inglese)
- https://blog.mindorks.com/introduction-to-dagger-2-using-dependency-injection-in-android-part-1-223289c2a01b
- https://blog.mindorks.com/introduction-to-dagger-2-using-dependency-injection-in-android-part-2-b55857911bcd
- https://blog.mindorks.com/the-new-dagger-2-android-injector-cbe7d55afa6a
- https://blog.mindorks.com/android-dagger2-critical-things-to-know-before-you-implement-275663aecc3e
- https://blog.mindorks.com/a-complete-guide-to-learn-dagger-2-b4c7a570d99c
- http://www.vogella.com/tutorials/Dagger/article.html
- https://medium.com/@iammert/new-android-injector-with-dagger-2-part-1-8baa60152abe