Anleitung für Dolch 2.x (überarbeitete Ausgabe 6) :
Die Schritte sind die folgenden:
1.)Dagger
zu deinen build.gradle
Dateien hinzufügen :
.
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' //added apt for source code generation
}
}
allprojects {
repositories {
jcenter()
}
}
- build.gradle auf App-Ebene :
.
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt' //needed for source code generation
android {
compileSdkVersion 24
buildToolsVersion "24.0.2"
defaultConfig {
applicationId "your.app.id"
minSdkVersion 14
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
apt 'com.google.dagger:dagger-compiler:2.7' //needed for source code generation
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.google.dagger:dagger:2.7' //dagger itself
provided 'org.glassfish:javax.annotation:10.0-b28' //needed to resolve compilation errors, thanks to tutplus.org for finding the dependency
}
2.) Erstellen Sie Ihre AppContextModule
Klasse, die die Abhängigkeiten bereitstellt.
@Module //a module could also include other modules
public class AppContextModule {
private final CustomApplication application;
public AppContextModule(CustomApplication application) {
this.application = application;
}
@Provides
public CustomApplication application() {
return this.application;
}
@Provides
public Context applicationContext() {
return this.application;
}
@Provides
public LocationManager locationService(Context context) {
return (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
}
}
3.) Erstellen Sie die AppContextComponent
Klasse, die die Schnittstelle zum Abrufen der injizierbaren Klassen bereitstellt.
public interface AppContextComponent {
CustomApplication application(); //provision method
Context applicationContext(); //provision method
LocationManager locationManager(); //provision method
}
3.1.) So würden Sie ein Modul mit einer Implementierung erstellen:
@Module //this is to show that you can include modules to one another
public class AnotherModule {
@Provides
@Singleton
public AnotherClass anotherClass() {
return new AnotherClassImpl();
}
}
@Module(includes=AnotherModule.class) //this is to show that you can include modules to one another
public class OtherModule {
@Provides
@Singleton
public OtherClass otherClass(AnotherClass anotherClass) {
return new OtherClassImpl(anotherClass);
}
}
public interface AnotherComponent {
AnotherClass anotherClass();
}
public interface OtherComponent extends AnotherComponent {
OtherClass otherClass();
}
@Component(modules={OtherModule.class})
@Singleton
public interface ApplicationComponent extends OtherComponent {
void inject(MainActivity mainActivity);
}
Achtung :: Sie müssen die @Scope
Annotation (wie @Singleton
oder @ActivityScope
) für die mit Annotationen @Provides
versehene Methode des Moduls angeben, um einen Anbieter mit Gültigkeitsbereich innerhalb Ihrer generierten Komponente zu erhalten. Andernfalls wird die Annotation aufgehoben und Sie erhalten bei jeder Injektion eine neue Instanz.
3.2.) Erstellen Sie eine Komponente mit Anwendungsbereich, die angibt, was Sie injizieren können (dies entspricht der injects={MainActivity.class}
in Dolch 1.x):
@Singleton
@Component(module={AppContextModule.class}) //this is where you would add additional modules, and a dependency if you want to subscope
public interface ApplicationComponent extends AppContextComponent { //extend to have the provision methods
void inject(MainActivity mainActivity);
}
3.3.) Für Abhängigkeiten, die Sie selbst über einen Konstruktor erstellen können und die Sie nicht mit einem neu definieren möchten @Module
(z. B. verwenden Sie stattdessen Build-Varianten, um den Implementierungstyp zu ändern), können Sie einen @Inject
kommentierten Konstruktor verwenden.
public class Something {
OtherThing otherThing;
@Inject
public Something(OtherThing otherThing) {
this.otherThing = otherThing;
}
}
Wenn Sie den @Inject
Konstruktor verwenden, können Sie auch die Feldinjektion verwenden, ohne explizit Folgendes aufrufen zu müssen component.inject(this)
:
public class Something {
@Inject
OtherThing otherThing;
@Inject
public Something() {
}
}
Diese @Inject
Konstruktorklassen werden automatisch zur Komponente desselben Bereichs hinzugefügt, ohne dass sie explizit in einem Modul angegeben werden müssen.
Eine Konstruktorklasse mit @Singleton
Gültigkeitsbereich @Inject
wird in @Singleton
Komponenten mit Gültigkeitsbereich angezeigt.
@Singleton // scoping
public class Something {
OtherThing otherThing;
@Inject
public Something(OtherThing otherThing) {
this.otherThing = otherThing;
}
}
3.4.) Nachdem Sie eine bestimmte Implementierung für eine bestimmte Schnittstelle definiert haben, gehen Sie wie folgt vor:
public interface Something {
void doSomething();
}
@Singleton
public class SomethingImpl {
@Inject
AnotherThing anotherThing;
@Inject
public SomethingImpl() {
}
}
Sie müssen die spezifische Implementierung mit a an die Schnittstelle "binden" @Module
.
@Module
public class SomethingModule {
@Provides
Something something(SomethingImpl something) {
return something;
}
}
Eine Abkürzung dafür seit Dolch 2.4 ist die folgende:
@Module
public abstract class SomethingModule {
@Binds
abstract Something something(SomethingImpl something);
}
4.) Erstellen Sie eine Injector
Klasse für Ihre Komponente auf Anwendungsebene (sie ersetzt die monolithische ObjectGraph
).
(Hinweis: Rebuild Project
Erstellen der DaggerApplicationComponent
Builder-Klasse mit APT)
public enum Injector {
INSTANCE;
ApplicationComponent applicationComponent;
private Injector(){
}
static void initialize(CustomApplication customApplication) {
ApplicationComponent applicationComponent = DaggerApplicationComponent.builder()
.appContextModule(new AppContextModule(customApplication))
.build();
INSTANCE.applicationComponent = applicationComponent;
}
public static ApplicationComponent get() {
return INSTANCE.applicationComponent;
}
}
5.) Erstelle deine CustomApplication
Klasse
public class CustomApplication
extends Application {
@Override
public void onCreate() {
super.onCreate();
Injector.initialize(this);
}
}
6.)CustomApplication
zu Ihrem hinzufügen AndroidManifest.xml
.
<application
android:name=".CustomApplication"
...
7.) Injizieren Sie Ihre Klassen inMainActivity
public class MainActivity
extends AppCompatActivity {
@Inject
CustomApplication customApplication;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Injector.get().inject(this);
//customApplication is injected from component
}
}
8.) Viel Spaß!
+1.) Sie können Scope
für Ihre Komponenten angeben, mit denen Sie Komponenten mit Aktivitätsbereich erstellen können . Mit Unterbereichen können Sie Abhängigkeiten bereitstellen, die Sie nur für einen bestimmten Unterbereich und nicht für die gesamte Anwendung benötigen. In der Regel erhält jede Aktivität mit diesem Setup ein eigenes Modul. Beachten Sie, dass pro Komponente ein Anbieter mit Gültigkeitsbereich vorhanden ist. Um die Instanz für diese Aktivität beizubehalten, muss die Komponente selbst die Konfigurationsänderung überstehen. Zum Beispiel könnte es durch überleben onRetainCustomNonConfigurationInstance()
oder ein Mörserfernrohr.
Weitere Informationen zum Subscoping finden Sie in der Anleitung von Google . Auch finden Sie diese Seite über Bereitstellung Methoden und auch die Komponentenabhängigkeiten Abschnitt ) und hier .
Um einen benutzerdefinierten Bereich zu erstellen, müssen Sie die Anmerkung zum Bereichsqualifizierer angeben:
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface YourCustomScope {
}
Um einen Unterbereich zu erstellen, müssen Sie den Bereich für Ihre Komponente angeben und ApplicationComponent
als Abhängigkeit angeben . Natürlich müssen Sie den Unterbereich auch in den Modulanbietermethoden angeben.
@YourCustomScope
@Component(dependencies = {ApplicationComponent.class}, modules = {CustomScopeModule.class})
public interface YourCustomScopedComponent
extends ApplicationComponent {
CustomScopeClass customScopeClass();
void inject(YourScopedClass scopedClass);
}
Und
@Module
public class CustomScopeModule {
@Provides
@YourCustomScope
public CustomScopeClass customScopeClass() {
return new CustomScopeClassImpl();
}
}
Bitte beachten Sie, dass nur eine Komponente mit Gültigkeitsbereich als Abhängigkeit angegeben werden kann. Stellen Sie sich das genau so vor, wie Mehrfachvererbung in Java nicht unterstützt wird.
+2.) Info @Subcomponent
: Im Wesentlichen kann ein Gültigkeitsbereich @Subcomponent
eine Komponentenabhängigkeit ersetzen. Anstatt jedoch einen vom Anmerkungsprozessor bereitgestellten Builder zu verwenden, müssten Sie eine Komponentenfactory-Methode verwenden.
Also das:
@Singleton
@Component
public interface ApplicationComponent {
}
@YourCustomScope
@Component(dependencies = {ApplicationComponent.class}, modules = {CustomScopeModule.class})
public interface YourCustomScopedComponent
extends ApplicationComponent {
CustomScopeClass customScopeClass();
void inject(YourScopedClass scopedClass);
}
Wird dies:
@Singleton
@Component
public interface ApplicationComponent {
YourCustomScopedComponent newYourCustomScopedComponent(CustomScopeModule customScopeModule);
}
@Subcomponent(modules={CustomScopeModule.class})
@YourCustomScope
public interface YourCustomScopedComponent {
CustomScopeClass customScopeClass();
}
Und das:
DaggerYourCustomScopedComponent.builder()
.applicationComponent(Injector.get())
.customScopeModule(new CustomScopeModule())
.build();
Wird dies:
Injector.INSTANCE.newYourCustomScopedComponent(new CustomScopeModule());
+3.): Bitte überprüfen Sie auch andere Fragen zum Stapelüberlauf in Bezug auf Dagger2. Sie enthalten viele Informationen. Zum Beispiel ist meine aktuelle Dagger2-Struktur in dieser Antwort angegeben .
Vielen Dank
Vielen Dank für die Anleitungen bei Github , TutsPlus , Joe Steele , Froger MCS und Google .
Auch für diese Schritt-für-Schritt-Anleitung zur Migration habe ich nach dem Schreiben dieses Beitrags gefunden.
Und zur Erklärung des Umfangs durch Kirill.
Noch mehr Informationen in der offiziellen Dokumentation .