I have read and watched a lot of different Dagger2 tutorials but most of them are too long or hard to understand so I decided to write a new simple and short tutorial for Dagger2, I hope you like it.
SharedPrefrences
then we can declare fields with a simple @Inject
annotation.Full source of example is available on my GitHub account.
First of all we need to add Dagger2 dependencies, Put below code to your module-level build.gradle file.
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"
If you are getting an error like Error:Conflict with dependency 'com.google.code.findbugs:jsr305' in project ':app' you should add the following to your main app/build.gradle file.
configurations.all {
resolutionStrategy.force 'com.google.code.findbugs:jsr305:3.0.1'
}
We have two classes (Vehicle and Motor), Vehicle class needs Motor class to run and MainActivity needs Vehicle class. We will use Dagger2 to provide these instances.
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 class:
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 class is responsible for providing objects which can be injected, In this example we want to inject Motor class to Vehicle class and inject Vehicle class to MainActivity so we should create MyModule to providing these instances.
@Module
class MyModule {
@Provides
@Singleton
Motor provideMotor() {
return new Motor();
}
@Provides
@Singleton
Vehicle provideVehicle() {
return new Vehicle(new Motor());
}
}
@Provide annotation: returned object from this method is available for dependency injection.
Dagger2 needs component interface to know how should it create instances from our classes.
@Singleton
@Component(modules = {MyModule.class})
interface MyComponent {
Vehicle provideVehicle();
void inject(MainActivity main);
}
@Component interface: connection between the provider of object and the objects which express a dependency.
By adding @Inject annotation, dagger2 can automatically create an instance from that object like our example Motor object in Vehicle class.
Dagger2 can automatically inject dependencies in constructors, but Android components (activities, fragments, etc.) are instantiated by Android framework which makes it difficult to use dependency injection on them, so we should inject them manually like below 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);
}
}
That's it, I hope you enjoy.