2016-11-22 23 views
1

使用dagger2Dagger2子注入項目是空

修訂

我有電腦和waterpump類汽車類的簡單例子。我通過爲什麼電機中的子注入零件爲空來寫它們?

這是我的電機類與startEngin方法,檢查計算機和waterPump啓動。

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; 
     } 
    } 

} 

,這是有型號和電壓計算機類:

public class Computer { 

    private int vultage; 
    private String model; 

    public Computer(String model ,int vultage){ 

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

,這是WaterPump:

public class WaterPump { 

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

這是我的模塊:

@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; 
    } 

} 

這是我的組件類,我知道這一點沒有必要獲取Motor方法。

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

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

,並在這裏活動注入電機爲空:

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

看http://stackoverflow.com/questions/31372901/android-dagger-2-dependency-not-being-injected和變化'注入(活動活動)''來注入(MainActivity mainActivity)'。您需要指定注射部位的編譯時類型 - '無效注射(活動活動)'將無法正常工作。 –

+1

@DavidRawson OK現在汽車是不是空在您的幫助,但注射部位在汽車是零,而不是注射。 – Kenji

回答

2

對我來說一切都很順利,除了Motor類本身。你用@Inject註釋了兩個字段(所以Dagger現在知道它可以在那裏注入東西),但是你永遠不會要求Dagger用數據「填充」這些變量。 您應該明確請求在代碼中的某處填寫這些數據。 1的方式來做到這一點是通過「構造函數注入」,因此多數民衆贊成如何構造函數應該像

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

...和模塊:

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

或者你可以從打電話的匕首比如你電機的建築師並做類似的事情:

myDaggerInstance.inject(this); 

並記住使用@Inject註釋爲Motor註釋構造函數。

無論使用哪種方法,您都明確告訴Dagger在某個時間點完成這些依賴關係,因此它們不再爲空。乾杯!

+0

感謝解決。那是我不想在構造函數中傳遞的點,但沒有爲方法創建注入方法。 +1並接受 – Kenji

+0

樂意幫忙! :)不過,在我看來,你應該考慮將來在構造函數中傳遞東西,因爲它提高了可讀性,模塊性和代碼可測試性(例如,在測試過程中,您可以將「真實」依賴與不同的東西 - 用.inject()填充數據,你不能真正改變或嘲笑它的行爲)。 –

+1

好的我會記得的;) – Kenji

1

您需要保存參考MotorComponent實例,並用它來注入Activtiy和汽車類。 將void inject(Motor m)添加到您的組件中,並調用component.inject(myMotor),或者在Motor類上使用構造函數注入。

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

你能說清楚我的代碼中的例子嗎? – Kenji

+0

這也許有效,但WaterPump和計算機沒有與匕首注射,它們是由構造函數。 – Kenji

+0

感謝它使用完整。但我想用@Inject – Kenji

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

而且

public class Motor { 

    @Inject 
    public Computer computer; 

    @Inject 
    public WaterPump waterPump; 


    public Motor(){ 
    } 

應爲下列之一:

1。)

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

    @Inject 
    public WaterPump waterPump; 

    @Inject 
    public Motor() { 
    } 

而且

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(); 
//} 

或者

2)

public class Motor { 
    public Computer computer; 

    public WaterPump waterPump; 

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

而且

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

我認爲你正在尋找解決方案#1 – EpicPandaForce