2016-11-22 4 views
1

einfaches Beispiel für die Verwendung von dagger2Dagger2 Unter injiziert Artikel ist null

AKTUALISIERT

ich einen Motor Klasse, die Computer-und Wasserstrahl Klasse. Ich schreibe sie so, warum sub injizierte Teile in Motor null ist?

Dies ist meine Motorklasse mit StartEngin Methode, die Computer und Wasserpumpe zu starten.

public class Motor { 

    @Inject 
    public Computer computer; 

    @Inject 
    public WaterPump waterPump; 


    public Motor(){ 
    } 

// here computer and waterPump are null and not injected 
    public boolean startEngin(){ 
     if(computer!=null && waterPump!=null){ 
      return true; 
     }else{ 
      return false; 
     } 
    } 

} 

und das ist Klasse-Computer, der Modellname und Spannung haben:

public class Computer { 

    private int vultage; 
    private String model; 

    public Computer(String model ,int vultage){ 

     this.model=model; 
     this.vultage = vultage; 
    } 
} 

und das ist Wasserpumpenrad:

public class WaterPump { 

    private String name; 
    public WaterPump(String name){ 
     this.name = name; 
    } 
} 

das ist mein Modul:

@Module 
public class MotorModule { 

    Context context; 
    String motoName; 
    String computerName; 
    String waterPupName; 
    int voltage; 

    public MotorModule(Context context, String computerName, String waterPupName, int voltage) { 
     this.context = context; 
     this.waterPupName = waterPupName; 
     this.computerName = computerName; 
     this.voltage = voltage; 
    } 

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

    @Provides 
    @Singleton 
    Computer provideComputer() { 
     return new Computer(computerName, voltage); 
    } 

    @Provides 
    @Singleton 
    WaterPump provideWaterPump() { 
     return new WaterPump(waterPupName); 
    } 

    @Provides 
    @Singleton 
    Context provideContext() { 
     return this.context; 
    } 

} 

und das ist meine Komponente Klasse, das weiß ich es gibt keine Notwendigkeit, Motor-Methode zu bekommen.

@Singleton 
@Component(modules = {MotorModule.class}) 
public interface MotorComponent { 

// Motor getMotor(); 
    void inject(MainActivity activty); 

und hier in Aktivität injiziert Motor null ist:

public class MainActivity extends AppCompatActivity { 

    @Inject 
    public Motor motor; 

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

     DaggerMotorComponent.builder().motorModule(new MotorModule 
       (this, "mahdi'PC", "my " + 
         "Water pump", 12)).build().inject(this); 

     if (motor.startEngin()) { 

      Toast.makeText(this, "it is started", Toast.LENGTH_SHORT).show(); 
     } else { 
      Toast.makeText(this, "motor is not provided", Toast.LENGTH_SHORT).show(); 
     } 

    } 

} 

} 
+1

siehe http://stackoverflow.com/questions/31372901/android-dagger-2-dependency-not-being-injected und ändere 'inject (Aktivitätsaktivität)' in 'inject (MainActivity mainActivity)'. Sie müssen den Kompilierungszeittyp der Injektionsstelle angeben - "void inject (Aktivitätsaktivität)" wird nicht funktionieren. –

+1

@DavidRawson ok jetzt Motor ist nicht null mit Ihrer Hilfe, aber injizierte Teile in Motor ist null und nicht injiziert. – Kenji

Antwort

2

Alles sieht OK für mich aus, außer für die Motorklasse selbst. Sie haben zwei Felder mit @Inject kommentiert (so weiß Dagger nun, dass es dort Dinge injizieren kann), aber Sie fordern Dagger niemals dazu auf, diese Variablen mit Daten zu füllen. Sie sollten explizit verlangen, diese Daten irgendwo in Ihrem Code zu füllen. 1 Weg, es zu tun ist durch ‚Konstruktor Injektion‘, so das ist, wie Ihr Konstruktor wie

public Motor(Computer computer, WaterPump waterPump) { 
this.computer = computer; 
this.waterPump = waterPump; 
} 

... und in Modul aussehen sollte:

@Provides 
@Singleton 
Motor provideMotor(Computer computer, Waterpump waterpump) { 
    return new Motor(computer, waterpump); 
} 

oder könnten Sie nennen Dolch Instanz von Ihrem Motor des consctructor und so etwas wie:

myDaggerInstance.inject(this); 

und erinnern Konstruktor mit @Inject Anmerkung für Motor mit Anmerkungen versehen.

In beiden Fällen haben Sie Dagger ausdrücklich angewiesen, diese Abhängigkeiten zu einem bestimmten Zeitpunkt zu erfüllen, damit sie nicht mehr null sind. Prost!

+0

danke lösen. Das war der Punkt, den ich im Konstruktor nicht übergeben wollte, aber keine Inject-Methode für die Methode erstellt habe. +1 und akzeptiert – Kenji

+0

Gerne helfen! :) Meiner Meinung nach sollte man in der Zukunft trotzdem etwas im Konstruktor übergeben, weil es die Lesbarkeit, Modularität und Codetestbarkeit verbessert (zB während des Tests kann man "echte" Abhängigkeiten mit gespotteten austauschen, die verschiedene Dinge tun - wenn man das tut) Fülle Daten mit .inject(), du kannst das Verhalten nicht wirklich ändern oder verspotten). –

+1

ok Ich werde daran denken;) – Kenji

1

Sie müssen Verweis auf MotorComponent Instanz speichern und verwenden Sie es in Activtiy und Motor Klassen zu injizieren. Fügen Sie void inject (Motor m) in Ihre Komponente ein, und rufen Sie component.inject (myMotor) auf, oder verwenden Sie stattdessen die Konstruktorinjektion für die Motorklasse.

public class Motor { 

    Computer computer; 
    WaterPump waterPump; 


    public Motor(Computer computer, WaterPump waterPump){ 
     this.computer = computer; 
     this.waterPump = waterPump; 
    } 

    // here computer and waterPump are null and not injected 
    public boolean startEngin(){ 
     if(computer!=null && waterPump!=null){ 
      return true; 
     }else{ 
      return false; 
     } 
    } 

} 

/** Add method, providing Motor class instance - it will use another 
.provide() methods from this component to get computer and waterpump objects 
(Costtructor injection) 
*/ 

    /** 
    * Arguments is provided by DI 
    * @param computer 
    * @param waterPump 
    * @return 
    */ 
    @Provides 
@Singleton 
Motor provideMotors(Computer computer, WaterPump waterPump) { 
    Motor motor = new Motor(computer, waterPump); 
     return motor 
} 

/** Store reference to your component (better do it in Application) */ 

MotorComponent component = DaggerMotorComponent.builder().motorModule(new MotorModule 
     (this, "mahdi'PC", "my " + 
       "Water pump", 12)).build(); 

// inject into Activity 
componen.inhject(this); 
+0

können Sie mit einem Beispiel aus meinem Code klären? – Kenji

+0

das funktioniert vielleicht aber WaterPump und Computer nicht mit Dolch injiziert, sie werden von Konstruktor übergeben. – Kenji

+0

danke es ist voll. aber ich möchte mit @inject – Kenji

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

Und

public class Motor { 

    @Inject 
    public Computer computer; 

    @Inject 
    public WaterPump waterPump; 


    public Motor(){ 
    } 

Sollte eine der folgenden sein:

1.

)
@Singleton 
public class Motor { 
    @Inject 
    public Computer computer; 

    @Inject 
    public WaterPump waterPump; 

    @Inject 
    public Motor() { 
    } 

Und

public MotorModule(Context context, String computerName, String waterPupName, int voltage) { 
    this.context = context; 
    this.waterPupName = waterPupName; 
    this.computerName = computerName; 
    this.voltage = voltage; 
} 

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

Oder

2.)

public class Motor { 
    public Computer computer; 

    public WaterPump waterPump; 

    public Motor(Computer computer, WaterPump waterPump) { 
     this.computer = computer; 
     this.waterPump = waterPump; 
    } 

Und

@Provides 
@Singleton 
Motor provideMotor(Computer computer, WaterPump waterPump) { 
    return new Motor(computer, waterPump); 
} 
+0

Ich denke, Sie suchen nach Lösung # 1 – EpicPandaForce

Verwandte Themen