For making things simple, suppose I want to inject EmailValidator from apache validators into my activity:
public class MainActivity extends FragmentActivity {
@Inject
EmailValidator emailValidator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
I have a MainModule class:
@Module
public class MainModule {
@Provides
public EmailValidator providesEmailValidator() {
return EmailValidator.getInstance();
}
}
and MainComponent interface:
@Singleton
@Component(modules = MainModule.class)
public interface MainComponent {
EmailValidator getEmailValidator();
}
When trying to use my validator in activity, I'm getting a nullpointer exception:
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean org.apache.commons.validator.routines.EmailValidator.isValid(java.lang.String)' on a null object reference
Obviously I'm missing something. I know that dagger creates component implementation for me. Should I use it? How?
If I do the following in my onCreate method:
emailValidator = Dagger_MainComponent.create().getEmailValidator();
then everything works fine.
But I want to be able to use @Inject annotation anywhere (probably on setter/constructor instead of a field) instead.
What am I missing?
I did something similar with dagger1 and it worked. Of course I needed to call ObjecGraph.inject(this)
in activity. What's the dagger2 equivalent?
EDIT:
Ok, so I've found a solution. If anyone will ever have such a problem, there are some snippets:
1) I've created an application class:
public class EmailSenderApplication extends Application {
private MainComponent component;
@Override
public void onCreate() {
super.onCreate();
component = Dagger_MainComponent
.create();
component.inject(this);
}
public MainComponent component() {
return component;
}
}
2) In AndroidManifest.xml:
<application
android:name=".EmailSenderApplication"
...
3) And finally, in the activity class where I want to inject some components those two ugly as hell lines:
component = ((EmailSenderApplication) getApplication()).component();
component.inject(this);
Dagger 2 is a compile-time android dependency injection framework that uses Java Specification Request 330 and Annotations. Some of the basic annotations that are used in dagger 2 are: @Module This annotation is used over the class which is used to construct objects and provide the dependencies.
Dagger is a fully static, compile-time dependency injection framework for Java, Kotlin, and Android. It is an adaptation of an earlier version created by Square and now maintained by Google.
inject. Inject annotation to identify which constructors and fields it is interested in. Use @Inject to annotate the constructor that Dagger should use to create instances of a class. When a new instance is requested, Dagger will obtain the required parameters values and invoke this constructor.
Dagger automatically generates code that mimics the code you would otherwise have hand-written. Because the code is generated at compile time, it's traceable and more performant than other reflection-based solutions such as Guice. Note: Use Hilt for dependency injection on Android.
Looks like you need to build your component as in:
component = Dagger_ MainComponent.builder()
.mainModule(new MainModule())
.build();
Typically, you do this in the onCreate
method of your Application.
One good resource that may help you is the example apps in the Dagger 2 repo.
I also found this PR helpful, from a suggested update to Jake Wharton's u2020 sample app (from the main Dagger 2 Engineer). It gives a good overview of the changes you need to make when going from Dagger 1 to 2 and, apparently that's what he points people to as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With