Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dagger2 - null instead of injected object

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);
like image 805
slnowak Avatar asked Feb 25 '15 16:02

slnowak


People also ask

What is dagger2 and why do you use it?

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.

What is dagger dependency injection?

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.

What is constructor injection in dagger?

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.

Why Dagger is used in Android?

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.


1 Answers

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.

like image 118
gMale Avatar answered Oct 22 '22 07:10

gMale