Kenji Kenji - 11 days ago 5
Android Question

Dagger2 sub injected item is null

simple example of using dagger2

UPDATED

I have a Motor class that have Computer and waterpump class. I write them like this by why sub injected parts in Motor is null?

this is my motor class with startEngin method that check computer and waterPump to start.

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

}


and this is Computer class that have model name and voltage:

public class Computer {

private int vultage;
private String model;

public Computer(String model ,int vultage){

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


and this is WaterPump:

public class WaterPump {

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


this is my Module:

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

}


and this is my component class, I know that there is no need to getMotor method.

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

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


and here in activity injected motor is null:

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

}

}

}

Answer

Everything looks OK to me, except for Motor class itself. You annotated two fields with @Inject (so Dagger now knows that it can inject stuff there), but you never actually request Dagger to 'fill' those variables with data. You should explicitly request filling those data somewhere in your code. 1 way to do it is through 'constructor injection', so thats how your constructor should look like

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

...and in module:

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

OR you could call dagger instance from your Motor's consctructor and do something like:

myDaggerInstance.inject(this);

and add this line to your component:

@Singleton
@Component(modules = {MotorModule.class})
public interface MotorComponent {
    void inject(Motor motor);
    void inject(MainActivity activty);

Using either way, you explicitly told Dagger to fulfill those dependencies at some point in time, so they won't be null anymore. Cheers!

Comments