MVP et Dagger 2 - Squelette d'application Android - Partie 2

Cet article est le résultat d'une recherche, dont le sous-produit était l'incarnation d'une idée de longue date dans une application Android très utile et manquante - My Location Notifier , conçue pour informer automatiquement le destinataire de l'arrivée d'un utilisateur (voir la description détaillée ici ).

Ainsi, dans la première partie, nous avons construit le squelette principal de l'application Android conformément à l'architecture MVP. Commençons maintenant à visser Dagger 2.

2.1. Preset

Pour commencer, accédez au fichier build.gradle (Project: mymvcapp) et ajoutez la ligne suivante à la section buildscript:

ext.dagger2_version = "2.8" 

Au moment d'écrire ces lignes, il s'agit de la dernière version de Dagger 2. Ensuite, accédez au fichier build.gradle (Module: app) et ajoutez la ligne au début:

 apply plugin: 'kotlin-kapt' 

Ceci est nécessaire pour que dans Dagger 2 il puisse générer son code lors de la compilation. Plus tard, vous comprendrez pourquoi.

Ajoutez maintenant les dépendances nécessaires:

 implementation "com.google.dagger:dagger:$dagger2_version" kapt "com.google.dagger:dagger-compiler:$dagger2_version" 

2.2. Préparation d'injection

Nous synchroniserons le projet et reviendrons au composant MainScreen. Créez une classe di.MainScreenModule dans le package backstage et marquez-la avec l'annotation Module . Dans la nouvelle classe, nous déclarons et implémentons la méthode providesPresenter (): MainScreenPresenter = MainScreenPresenter et la marquons avec des annotations Provides et Singleton . Alors maintenant, notre classe regardera:

 @Module class MainScreenModule { @Provides @Singleton fun providesPresenter(): MainScreenPresenter = MainScreenPresenter() } 

Passons maintenant à la classe MainScreenCompatActivity et remplaçons les modificateurs de la variable de présentateur par lateinit var, supprimons l'affectation de valeur et marquons-la avec l'annotation Inject :

 class MainScreen : BaseCompatActivity(), MainScreenContract.View { @Inject lateinit var presenter: MainScreenPresenter override fun init(savedInstanceState: Bundle?) { setContentView(R.layout.activity_main_screen) presenter.attach(this) } } 

Notez que nous n'avons plus besoin d'un point d'interrogation pour accéder à cette variable.
Il peut sembler que tout est injecté, la tâche est terminée. Mais non. Maintenant, nous devons obtenir Dagger pour générer le code nécessaire pour injecter notre première dépendance. C'est pourquoi nous avons ajouté le plugin kotlin-kapt au script de construction ci-dessus. Dans le package com.caesar84mx.mymvcapp, créez le package di.config dans lequel nous allons créer l'interface AppDiComponent.



Maintenant, déclarons l'interface un composant et un singleton et un misérable , enregistrons notre module dedans et déclarons la méthode d'injection (mainScreenActivity: MainScreen) à l'intérieur de l'interface:

 @Component( modules = [ MainScreenModule::class ] ) @Singleton interface AppDiComponent { fun inject(mainScreenActivity: MainScreen) } 

Et maintenant, vous devez enfin faire en sorte que Dagger génère tout le code nécessaire. Pour ce faire, nous allons créer la classe MyMvpApp dans le package config.di, l'hériter de la classe Application, enregistrer la classe dans AndroidManifest.xml en écrivant la ligne android: name = ". Config.di.MyMvpApp" dans la balise d'application. Ensuite, déclarez l'injecteur var Lateinit variable: AppDiComponent, définissez-le sur un setter privé et redéfinissez la méthode onCreate (). Et lancez la magie:

 class MyMvpApp: Application() { lateinit var injector: AppDiComponent private set override fun onCreate() { super.onCreate() injector = DaggerAppDiComponent.builder() .mainScreenModule(MainScreenModule()) .build() } } 

Comme vous pouvez le voir, la classe DaggerAppDiComponent n'existe pas encore, elle sera générée lors de la génération de l'application. Ainsi que la mise en place de notre composante. Le nom de classe est composé du mot "Dagger" + du nom de l'interface marquée comme composant. La méthode mainScreenModule () sera également générée lors de la construction du projet, le nom doit être composé du nom de classe du module injecté dans lowerCamelCase.

Nous assemblons le projet (Build → Make Project). Profitez de la génération automatique de code et continuez.

2.3. L'injection

Attention: en plus, quelques danses avec un tambourin avec des éléments de pornographie seront présentées. La demande de supprimer les enfants et les personnes nerveuses de l'écran.

Pour des injections réussies, nous aurons besoin d'une référence à la variable injecteur. D'accord, la création d'une instance de MyMvpApp dans chaque classe où nous injectons n'est pas la meilleure solution. Par conséquent, nous ferons ce qui suit:

 class MyMvpApp: Application() { lateinit var injector: AppDiComponent private set override fun onCreate() { super.onCreate() INSTANCE = this injector = DaggerAppDiComponent.builder() .mainScreenModule(MainScreenModule()) .build() } companion object { private var INSTANCE: MyMvpApp? = null @JvmStatic fun get(): MyMvpApp = INSTANCE!! } } 

Expiré, retourné à la classe MainScreen. Maintenant, injectez notre présentateur dans la méthode init (). N'oubliez pas que cette action doit être effectuée avant le premier accès à la variable injectée. Alors maintenant, notre classe ressemble à:

 class MainScreen : BaseCompatActivity(), MainScreenContract.View { @Inject lateinit var presenter: MainScreenPresenter override fun init(savedInstanceState: Bundle?) { setContentView(R.layout.activity_main_screen) MyMvpApp.get().injector.inject(this) presenter.attach(this) } } 

Et voici toute la structure de base de notre application:



2.4. Conclusion

Nous sommes donc prêts pour la structure minimale de l'application, sur laquelle il ne reste plus qu'à accrocher les éléments. Besoin d'une nouvelle activité? Nous le représentons comme un composant, séparé de l'interface utilisateur des coulisses, pour chaque composant, nous déterminons les dépendances dont nous avons besoin (minimum, le présentateur en activité, ou peut-être dans le présentateur lui-même l'API pour interagir avec un service distant, ou, par exemple, l'API de référentiel pour travailler avec la base de données), enregistrez le module avec les dépendances, enregistrez le module dans le composant, inscrivez-vous dans le générateur, reconstruisez le projet, injectez les dépendances si nécessaire, répétez l'itération pour chaque nouveau composant.

Bien sûr, la question peut se poser: pourquoi avons-nous besoin de Dagger? Après tout, ils ont fait un excellent travail, non? Génial, même si l'application est petite. Quand il s'agrandira, avec des dizaines d'activités, de fragments, d'adaptateurs, de demandes de serveur, de mise en cache des données et d'autres merveilles, il y aura de nombreuses dépendances difficiles à suivre dans une grande application si vous n'utilisez pas l'injection de dépendances. Le cadre Dagger DI permet de simplifier la tâche de mise en œuvre et de suivi.

Source: https://habr.com/ru/post/fr434618/


All Articles