Vorheriger TeilInhalt
- Implementieren Sie Methoden und Felder
- Verzögerte Initialisierung im Dolch
- Dolchmodule. Wenn der Dolch dich nicht versteht
- Zusammenfassung benannt. Mehrere Instanzen desselben Typs
Implementieren Sie Methoden und FelderDer erste Teil beschreibt eine Methode zum Implementieren von Abhängigkeiten auf Konstruktorebene. Darüber hinaus kann Dolch Abhängigkeiten für Felder und Methoden implementieren. Diese Implementierungen sollten jedoch verwendet werden, wenn dies unbedingt erforderlich ist.
Beispiel für die Methodenimplementierung:
class Car @Inject constructor(private var engine: Engine){ var key: Key? = null @Inject set } class Key @Inject constructor()
Im obigen Beispiel ist die festgelegte Methodenabhängigkeit für das Schlüsselfeld implementiert
Die Implementierung der Felder erfolgt in drei Schritten:
- Fügen Sie der abstrakten Factory eine Einbettungsmethode hinzu
- Definieren Sie die zu implementierenden Felder
- Verwenden Sie Implementierungsmethoden in einer Implementierung eines abstrakten Klassendolches, um Abhängigkeiten zu implementieren
Es wird eindeutig einfacher sein, dies der Reihe nach zu verstehen
1. Fügen Sie in unserer abstrakten Klasse eine Implementierungsmethode für MainActivity hinzu
@Component interface DaggerComponent { fun getCar(): Car fun getEngine(): Engine fun getFuel(): Fuel fun inject(act: MainActivity) }
2. Definieren Sie die Felder, die in MainActivity implementiert werden sollen. Injizierte Felder müssen lateinit var sein und für alle sichtbar sein (öffentlich)
@Injected lateinit var car: Car
3. Wir rufen die hinzugefügte Methode inj () der abstrakten Klasse zum Implementieren der Aktivitätsfelder auf.
Letztendlich sieht unsere MainActivity-Klasse wie eine Spur aus. Weg:
class MainActivity : AppCompatActivity() { @Inject lateinit var car: Car override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) DaggerDaggerComponent.create().inject(this) } }
Verzögerte Initialisierung im DolchWie Sie wissen, werden beim Starten einer Anwendung nicht immer Instanzen aller Klassen benötigt. Dies beschleunigt den ersten Start und mehr. Es gibt zwei Arten der Initialisierung eingebetteter Objekte in Dolch: Provider <> und Lazy <>
Provider - Die Initialisierung erfolgt beim ersten Aufruf des Objekts und bei jedem Aufruf wird eine neue Instanz des Objekts zurückgegeben
Lazy - Die Initialisierung erfolgt beim ersten Aufruf, dann werden zuvor zwischengespeicherte Instanzen zurückgegeben
Um diese Arten der Initialisierung zu verwenden, müssen die initialisierten Objekte in der gewünschten Form "umbrochen" werden.
Beispiel für die Verwendung des Anbieters:
class Engine @Inject constructor(private var fuel: Fuel){ fun start(){ if(fuel!=null){ print("Started!") }else{ print("No more fuel!") } } } class Car @Inject constructor(private var engine: Provider<Engine>){ var key: Key? = null @Inject set fun startCar(){ engine.get().start() } } class Key @Inject constructor()
Jedes Mal, wenn die Methode get () aufgerufen wird, erhalten wir eine neue Instanz des gewünschten Objekts.
Ein Beispiel für die Verwendung von Lazy:
class Fuel @Inject constructor() { val fuelType = if(BuildConfig.DEBUG){ "benzine" }else{ "diesel" } } class Engine @Inject constructor(private var fuel: Lazy<Fuel>){ fun start(){ if(fuel!=null){ print("Started with ${fuel.get().fuelType}") }else{ print("No more fuel!") } } }
Jedes Mal, wenn die get () -Methode aufgerufen wird, erhalten wir dieselbe Instanz.
Achtung! Wenn Sie die get () -Methode der Lazy-Ansicht in Android Studio hinzufügen, wird die Methode möglicherweise seitdem rot unterstrichen Kotlin hat eine eigene Lazy-Klasse. Also importieren wir die Dolchklasse
import dagger.Lazy
Dolchmodule. Wenn der Dolch dich nicht verstehtEs gibt Zeiten, in denen ein Dolch Ihre Absichten nicht versteht. Zum Beispiel hat unsere Car-Klasse ein Feld vom Typ (Schnittstelle) Driver, das von der Ivanov-Klasse geerbt wird
Wenn Sie versuchen, ein Feld mit einem Schnittstellentyp zu implementieren, wird die Fehlermeldung "Ohne Methoden mit @ Provides-Annotation kann nicht bereitgestellt werden" angezeigt.
Um dieses Problem zu lösen, schlägt Dolch die Verwendung von Modulen vor. Die Module versorgen den Dolch mit zusätzlichen Informationen, die er allein nicht erhalten kann. Als Module können Sie Schnittstellen oder Objekte (Objekt) verwenden.
Erstellen Sie ein Modul, um das oben genannte Problem zu lösen:
@Module interface DaggerModul { @Binds fun bindDriver(driver: Ivanov): Driver } class Ivanov @Inject constructor(): Driver
In der bindDriver-Methode erklären wir dem Dolch, wie die Schnittstelle initialisiert wird.
Außerdem müssen Sie in der Komponente alle vorhandenen Dolchmodule auflisten
@Component(modules = [DaggerModul::class]) interface DaggerComponent { … }
Angenommen, für unsere Klasse Engine wird das Feld des Bibliothekszylinders (Schnittstelle) eines Drittanbieters verwendet. Wie kann man ein solches Feld für Dolch beschreiben, wenn nicht klar ist, welche Klasse zur Laufzeit initialisiert wird?
Bisher haben wir Anmerkungen verwendet, um zu erklären, wie Abhängigkeiten eingefügt werden sollen. Was ist, wenn Sie beispielsweise nicht wissen, wie Sie Klassen aus ausländischen Bibliotheken erstellen können?
Mit Anmerkungen werden die Fälle beschrieben, in denen Sie eine Instanz explizit beschreiben müssen, welche Klasse Sie initialisieren möchten.
@Module object DaggerModuleObject { @Provides @JvmStatic fun getBoschCylinder(): Cylinder = BoschCylinder() }
Daher sagen wir Dolch, dass wir beim Initialisieren des Zylinderfelds eine Instanz der BoschCylinder-Klasse benötigen.
Zusammenfassung benannt . Mehrere Instanzen desselben TypsEs gibt Zeiten, in denen Sie Instanzen derselben Klasse mit unterschiedlichen Einstellungen erstellen müssen. In unserem Beispiel sind dies verschiedene Farben an Karosserie und Türen.
Beim Versuch, ein Projekt mit einer Ablaufverfolgung zu erstellen. Das Modul erhält die Fehlermeldung "(unsere Klasse) Farbe wird mehrfach gebunden"
@Provides @JvmStatic fun getColorRed():Color = Color("red") @Provides @JvmStatic fun getColorBlue():Color = Color("blue")
Um solche Fälle zu lösen, wird die Annotation
Named verwendet. Zunächst werden wir im Modul 3 neue Methoden zur Initialisierung in Dolch erstellen
@JvmStatic @Provides fun getColor(): Color = Color("") @Provides @Named("blueColor") @JvmStatic fun getColorBlue(): Color{ return Color("blue") } @JvmStatic @Named("redColor") @Provides fun getColorRed(): Color = Color("red")
Die erste Methode ist die Standardeinstellung. Ohne sie schwört der Dolch auf das Fehlen der Klasse "Kann nicht ohne einen Inject-Konstruktor oder eine mit Provides versehene Methode bereitgestellt werden."
Die folgenden beiden Methoden geben Instanzen derselben Klasse zurück. Es bleibt, die Implementierung dieser Klasse an den richtigen Stellen hinzuzufügen und mit der Annotation
Named aufzurufen
class Door @Inject constructor() { @Named("blueColor") @Inject lateinit var color:Color } class Car @Inject constructor(private var engine: Provider<Engine>, private var door: Door, var driver: Driver){ var key: Key? = null @Inject set @Inject @Named("redColor") lateinit var color: Color fun startCar(){ engine.get().start() } } class Key @Inject constructor()
Quellcode