Android
Dagger 2
Sök…
Syntax
- @Modul
- @Component (beroende = {OtherComponent.class}, modules = {ModuleA.class, ModuleB.class})
- DaggerMyComponent.create ()
- DaggerMyComponent.builder (). MyModule (newMyModule ()). Skapa ()
Anmärkningar
Att inte förväxla med dolk efter kvadrat, föregångaren till dolk 2.
Komponentinställning för applikations- och aktivitetsinjektion
En grundläggande AppComponent
som beror på en enda AppModule
att tillhandahålla applikationsomfattande singleton-objekt.
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(App app);
Context provideContext();
Gson provideGson();
}
En modul som kan användas tillsammans med AppComponent
som kommer att tillhandahålla dess singleton-objekt, t.ex. en instans av Gson
att återanvända hela applikationen.
@Module
public class AppModule {
private final Application mApplication;
public AppModule(Application application) {
mApplication = application;
}
@Singleton
@Provides
Gson provideGson() {
return new Gson();
}
@Singleton
@Provides
Context provideContext() {
return mApplication;
}
}
En underklassad applikation för att ställa in dolk och singleton-komponenten.
public class App extends Application {
@Inject
AppComponent mAppComponent;
@Override
public void onCreate() {
super.onCreate();
DaggerAppComponent.builder().appModule(new AppModule(this)).build().inject(this);
}
public AppComponent getAppComponent() {
return mAppComponent;
}
}
Nu är en aktivitetskopierad komponent som beror på AppComponent
att få tillgång till singletonobjekten.
@ActivityScope
@Component(dependencies = AppComponent.class, modules = ActivityModule.class)
public interface MainActivityComponent {
void inject(MainActivity activity);
}
Och en återanvändbar ActivityModule
som kommer att ge grundläggande beroenden, som en FragmentManager
@Module
public class ActivityModule {
private final AppCompatActivity mActivity;
public ActivityModule(AppCompatActivity activity) {
mActivity = activity;
}
@ActivityScope
public AppCompatActivity provideActivity() {
return mActivity;
}
@ActivityScope
public FragmentManager provideFragmentManager(AppCompatActivity activity) {
return activity.getSupportFragmentManager();
}
}
Att sätta ihop allt vi skapar och kan injicera vår aktivitet och se till att använda samma Gson
hela appen!
public class MainActivity extends AppCompatActivity {
@Inject
Gson mGson;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainActivityComponent.builder()
.appComponent(((App)getApplication()).getAppComponent())
.activityModule(new ActivityModule(this))
.build().inject(this);
}
}
Anpassade räckvidd
@Scope
@Documented
@Retention(RUNTIME)
public @interface ActivityScope {
}
Omfång är bara kommentarer och du kan skapa dina egna när det behövs.
Constructor Injection
Klasser utan beroende kan enkelt skapas av dolk.
public class Engine {
@Inject // <-- Annotate your constructor.
public Engine() {
}
}
Denna klass kan tillhandahållas av alla komponenter. Det har inga beroende i sig och är inte omfattat . Det behövs ingen ytterligare kod.
Beroenden deklareras som parametrar i konstruktören. Dolk kommer att ringa konstruktören och leverera beroenden så länge dessa beroenden kan tillhandahållas.
public class Car {
private Engine engine;
@Inject
public Car(Engine engine) {
this.engine = engine;
}
}
Denna klass kan tillhandahållas av varje komponent omm denna komponent kan också ge alla sina Dependencies- Engine
i detta fall. Eftersom Engine
också kan konstrueras som injektor kan alla komponenter ge en Car
.
Du kan använda konstruktionsinjektion när alla beroenden kan tillhandahållas av komponenten. En komponent kan ge ett beroende, om
- det kan skapa det med hjälp av konstruktionsinjektion
- en modul med komponenten kan tillhandahålla den
- den kan tillhandahållas av överkomponenten (om det är en
@Subcomponent
) - det kan använda ett objekt som exponeras av en komponent det beror på (komponentberoenden)
Använda @Subcomponent istället för @Component (beroende = {...})
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
void inject(App app);
Context provideContext();
Gson provideGson();
MainActivityComponent mainActivityComponent(ActivityModule activityModule);
}
@ActivityScope
@Subcomponent(modules = ActivityModule.class)
public interface MainActivityComponent {
void inject(MainActivity activity);
}
public class MainActivity extends AppCompatActivity {
@Inject
Gson mGson;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((App)getApplication()).getAppComponent()
.mainActivityComponent(new ActivityModule(this)).inject(this);
}
}
Hur man lägger till Dagger 2 i build.gradle
Sedan Gradle 2.2 släpptes används inte längre Android-plugin-pluginet. Följande metod för att ställa in Dagger 2 bör användas. För äldre version av Gradle, använd föregående metod som visas nedan.
För Gradle> = 2.2
dependencies {
// apt command comes from the android-apt plugin
annotationProcessor 'com.google.dagger:dagger-compiler:2.8'
compile 'com.google.dagger:dagger:2.8'
provided 'javax.annotation:jsr250-api:1.0'
}
För Gradle <2.2
För att använda Dagger 2 är det nödvändigt att lägga till android-apt
plugin, lägg till detta till root build.gradle:
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
Då bör applikationsmodulens build.gradle innehålla:
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
android {
…
}
final DAGGER_VERSION = '2.0.2'
dependencies {
…
compile "com.google.dagger:dagger:${DAGGER_VERSION}"
apt "com.google.dagger:dagger-compiler:${DAGGER_VERSION}"
}
Referens: https://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2
Skapa en komponent från flera moduler
Dagger 2 stöder att skapa en komponent från flera moduler. Du kan skapa din komponent på detta sätt:
@Singleton
@Component(modules = {GeneralPurposeModule.class, SpecificModule.class})
public interface MyMultipleModuleComponent {
void inject(MyFragment myFragment);
void inject(MyService myService);
void inject(MyController myController);
void inject(MyActivity myActivity);
}
De två referensmodulerna GeneralPurposeModule
och SpecificModule
kan sedan implementeras enligt följande:
GeneralPurposeModule.java
@Module
public class GeneralPurposeModule {
@Provides
@Singleton
public Retrofit getRetrofit(PropertiesReader propertiesReader, RetrofitHeaderInterceptor headerInterceptor){
// Logic here...
return retrofit;
}
@Provides
@Singleton
public PropertiesReader getPropertiesReader(){
return new PropertiesReader();
}
@Provides
@Singleton
public RetrofitHeaderInterceptor getRetrofitHeaderInterceptor(){
return new RetrofitHeaderInterceptor();
}
}
SpecificModule.java
@Singleton
@Module
public class SpecificModule {
@Provides @Singleton
public RetrofitController getRetrofitController(Retrofit retrofit){
RetrofitController retrofitController = new RetrofitController();
retrofitController.setRetrofit(retrofit);
return retrofitController;
}
@Provides @Singleton
public MyService getMyService(RetrofitController retrofitController){
MyService myService = new MyService();
myService.setRetrofitController(retrofitController);
return myService;
}
}
Under beroendeinjektionsfasen tar komponenten objekt från båda modulerna efter behov.
Denna metod är mycket användbar när det gäller modularitet . I exemplet finns en modul för allmänt bruk som används för att instansera komponenter som Retrofit
objektet (används för att hantera nätverkskommunikationen) och en PropertiesReader
(ansvarig för hantering av konfigurationsfiler). Det finns också en specifik modul som hanterar inställningen av specifika styrenheter och serviceklasser i relation till den specifika applikationskomponenten.