2016-11-22 22 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