dagger-2Aan de slag met dolk-2


Opmerkingen

Deze sectie geeft een overzicht van wat dagger-2 is en waarom een ontwikkelaar het misschien wil gebruiken.

Het moet ook alle grote onderwerpen in dagger-2 vermelden en naar de gerelateerde onderwerpen verwijzen. Aangezien de documentatie voor dagger-2 nieuw is, moet u mogelijk eerste versies van die gerelateerde onderwerpen maken.

versies

Versie Publicatiedatum
2.5 2016/06/14
2.6 2016/07/27
2.7 2016/09/13
2.8 2016/11/22
2.9 2017/02/03
2.10 2017/03/15

Android-voorbeeld

Een van de centrale problemen bij het schrijven van een Android-applicatie met Dagger is dat veel Android-frameworkklassen door het besturingssysteem zelf worden geïnstantieerd, zoals Activity en Fragment , maar Dagger werkt het beste als het alle geïnjecteerde objecten kan maken. In plaats daarvan moet u leden injecteren volgens een levenscyclusmethode. Vanaf versie 2.10 kunt u dagger.android wat het gebruik van dolk met Android-componenten vereenvoudigt.

Objecten injecteren

  1. Installeer AndroidInjectionModule in uw toepassingscomponent om ervoor te zorgen dat alle bindingen die nodig zijn voor deze AndroidInjectionModule beschikbaar zijn.

    @Component(modules = {AndroidInjectionModule.class})
    public interface AppComponent {}
     
  2. Begin met het schrijven van een @Subcomponent die [AndroidInjector] [AndroidInjector] implementeert, met een @Subcomponent.Builder die [AndroidInjector.Builder] [AndroidInjector.Builder] uitbreidt:

    @Subcomponent
    public interface MainActivityComponent extends AndroidInjector<MainActivity> {
        @Subcomponent.Builder
        abstract class Builder extends AndroidInjector.Builder<MainActivity> {}
    }
     
  3. Nadat u de subcomponent hebt gedefinieerd, voegt u deze toe aan uw componenthiërarchie door een module te definiëren die de subcomponentbouwer bindt en toevoegt aan de component die uw Application injecteert:

    @Module(subcomponents = MainActivityComponent.class)
    public abstract class MainActivityModule {
    
        @Binds @IntoMap @ActivityKey(MainActivity.class)
        abstract AndroidInjector.Factory<? extends Activity>
        bindMainActivityInjectorFactory(MainActivityComponent.Builder builder);
    }
     
  4. Maak vervolgens uw Application HasDispatchingActivityInjector en @Inject a DispatchingAndroidInjector<Activity> om terug te keren van de methode activityInjector ():

    public class MyApp extends Application implements HasDispatchingActivityInjector     {
    
        @Inject
        DispatchingAndroidInjector<Activity> dispatchingActivityInjector;
    
        @Override
        public void onCreate() {
           super.onCreate();
           DaggerAppComponent.create().inject(this);
        }
    
        @Override
        public DispatchingAndroidInjector<Activity> activityInjector() {
            return dispatchingActivityInjector;
        }
    }
     
  5. Ten slotte, in uw Activity.onCreate() methode, roept u AndroidInjection.inject(this) voordat u super.onCreate(); :

    public class MainActivity extends Activity {
        public void onCreate(Bundle savedInstanceState) {
            AndroidInjection.inject(this);
            super.onCreate(savedInstanceState);
        }
    }
     

Dit voorbeeld was gebaseerd op officiële dolkdocumentatie . Werkend monster is te vinden op github

Basis voorbeeld

Definieer een module (het model van afhankelijkheden en hun grafiek):

@Module
public class CoffeeModule{

    @Provides
    public CoffeeMaker provideCoffeeMaker(){
         return new CoffeeMaker();
    }

    @Provides
    public Coffee provideCoffee(CoffeeMaker coffeeMaker){
        return new Coffee(coffeeMaker);
    }

}
 

Definieer een component:

@Component(
    modules={
        CoffeeModule.class
    }
)
interface CoffeeComponent {

        DeveloperActivity inject(DeveloperActivity developerActivity);
}
 

Injecteer de afhankelijkheden:

class DeveloperActivity extends ...{

    @Inject
    Coffee myCoffee;

    @Override
    protected void onCreate(Bundle savedInstanceState) {           
        super.onCreate(savedInstanceState);

        DaggerCoffeeComponent.builder()
                .coffeeModule(new CoffeeModule())
                .build()
                .inject();
       
    }

}
 

Beschrijving en instellingen

Wat is Dagger 2?

De website beschrijft zichzelf als:

Dagger is een volledig statisch, afhankelijk van de compilatie afhankelijk van injectie

De bibliotheek maakt het gemakkelijk om afhankelijkheidsgrafieken te modelleren en objecten opnieuw te gebruiken. Omdat reflectie alleen tijdens het compileren wordt gebruikt als onderdeel van de annotatieverwerking, heeft Dagger 2 de snelheid voor injectie van afhankelijkheid verbeterd.

Opstelling

1- Voeg ondersteuning toe voor het verwerken van annotaties:

Android

build.gradle script:

 repositories {
    mavenCentral()
  }
  dependencies {
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
  }
 

Module level build.gradle script:

apply plugin: 'com.neenbedankt.android-apt'
 

Java

plugins {
  id "net.ltgt.apt" version "0.5"
}    
 

2- Voeg de afhankelijkheden van dolk 2 toe

 dependencies {
      compile 'com.google.dagger:dagger:2.x'
      apt 'com.google.dagger:dagger-compiler:2.x'
    }
 

Leer Dagger2 met eenvoudig voorbeeld

Ik heb veel verschillende Dagger2-tutorials gelezen en bekeken, maar de meeste zijn te lang of moeilijk te begrijpen, dus besloot ik een nieuwe eenvoudige en korte tutorial voor Dagger2 te schrijven, ik hoop dat je het leuk vindt.

Waarom hebben we het nodig?

  • Vereenvoudigt de toegang tot gedeelde gevallen: Het biedt een eenvoudige manier om verwijzingen naar gedeelde exemplaren te verkrijgen, bijvoorbeeld als we verklaren in Dagger onze singleton gevallen zoals SharedPrefrences dan kunnen we velden met een eenvoudig te verklaren @Inject annotatie.
  • Eenvoudigere unit- en integratietests: we kunnen eenvoudig modules uitwisselen die netwerkreacties uitvoeren en dit gedrag bespotten.

Lest begint met een eenvoudig voorbeeld

Volledige bron van voorbeeld is beschikbaar op mijn GitHub-account.

Voeg afhankelijkheden van Dagger2 toe

Allereerst moeten we Dagger2-afhankelijkheden toevoegen, onderstaande code toevoegen aan uw build.gradle-bestand op moduleniveau.

compile "com.google.dagger:dagger:$dagger_version"
compile "com.google.dagger:dagger-android:$dagger_version"
compile "com.google.dagger:dagger-android-support:$dagger_version"
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
 

Als u een foutmelding krijgt zoals Fout: conflict met afhankelijkheid 'com.google.code.findbugs: jsr305' in project ': app' moet u het volgende toevoegen aan uw hoofdbestand app / build.gradle.

configurations.all {
   resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1'
}
 

Twee eenvoudige klasse

We hebben twee klassen (voertuig en motor), voertuigklasse heeft motorklasse nodig om te draaien en MainActivity heeft voertuigklasse nodig. We zullen Dagger2 gebruiken om deze instanties te leveren.

class Vehicle {
   private Motor motor;

  @Inject
  Vehicle(Motor motor) {
     this.motor = motor;
  }

  void increaseSpeed(int value) {
     motor.accelerate(value);
  }

  void decreaseSpeed(int value) {
     motor.decelerate(value);
  }

  void stop() {
     motor.brake();
  }

  int getSpeed() {
     return motor.getRpm();
  }
}
 

Motor klasse:

class Motor {
  private int rpm;

  Motor() {
    this.rpm = 0;
  }

  int getRpm() {
    return rpm;
  }

  void accelerate(int value) {
    rpm += value;
  }

  void decelerate(int value) {
    rpm -= value;
  }

  void brake() {
    rpm = 0;
  }
}
 

Module klasse

De moduleklasse is verantwoordelijk voor het leveren van objecten die kunnen worden geïnjecteerd. In dit voorbeeld willen we de motorklasse injecteren naar de voertuigklasse en de voertuigklasse injecteren naar MainActivity, dus moeten we MyModule maken om deze instanties te leveren.

@Module
class MyModule {

  @Provides
  @Singleton
  Motor provideMotor() {
    return new Motor();
  }

  @Provides
  @Singleton
  Vehicle provideVehicle() {
    return new Vehicle(new Motor());
  }
}
 

@ Verstrek annotatie: geretourneerd object van deze methode is beschikbaar voor injectie van afhankelijkheid.

@Component-interface

Dagger2 heeft een componentinterface nodig om te weten hoe het instanties van onze klassen moet maken.

@Singleton
@Component(modules = {MyModule.class})
interface MyComponent {
  Vehicle provideVehicle();

  void inject(MainActivity main);
}
 

@Component-interface: verbinding tussen de aanbieder van het object en de objecten die een afhankelijkheid uitdrukken.

Injecteer afhankelijkheid in Constructor

Door annotatie met @Inject toe te voegen, kan dagger2 automatisch een instantie van dat object maken, zoals ons voorbeeld Motorobject in de klasse Vehicle.

Afhankelijkheid injecteren in MainClass

Dagger2 kan automatisch afhankelijkheden in constructors injecteren, maar Android-componenten (activiteiten, fragmenten, enz.) Worden geïnstantieerd door Android-framework waardoor het moeilijk is om afhankelijkheidsinjectie daarop te gebruiken, dus we moeten ze handmatig injecteren zoals onderstaande code:

public class MainActivity extends AppCompatActivity {
  @Inject
  Vehicle vehicle;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    MyComponent component = DaggerMyComponent.builder().build();
    component.inject(this);
  }
}
 

Dat is alles, ik hoop dat je ervan geniet.