1

I am creating multi module android project using java. I got Null when I inject a class. Followings are my codes.

SignupComponent.class

@FeatureScope
@Subcomponent(modules = SignupModule.class)
public interface SignupComponent {

    @Subcomponent.Factory
    interface Factory{
        SignupComponent create();
    }

    void inject(Activity_Signup activity_signup);

SignupModule.class

@Module
public class SignupModule {

    @FeatureScope
    @Provides
    public SignupContract.Presenter providePresenter(){
        return new SignupPresenter();
    }


}

Activity_Signup.class

SignupComponent signupComponent = ((SignupComponentProvider) getApplicationContext())
                .provideSignupComponent();
        //Inject the view
        signupComponent.inject(this);

SignupPresenter.class

 public class SignupPresenter implements SignupContract.Presenter {

    // this injection return Null
    @Inject
    public SignupUseCase signupUseCase;  


}

SignupUseCase.class

public class SignupUseCase {
    @Inject
    public SignupUseCase(){}
...
}

Why am I getting NPE?

EDIT

SignupModule.class

@Module
public class SignupModule {

    @FeatureScope
    @Provides
    public SignupContract.Presenter providePresenter(){
        return new SignupPresenter();
    }

    @FeatureScope
    @Provides
    public SignupUseCase provideUseCase(){
        return new SignupUseCase();
    }



}
pak
  • 55
  • 5

1 Answers1

2
@FeatureScope
@Provides
public SignupContract.Presenter providePresenter(){
    return new SignupPresenter();
}

When you call new SignupPresenter(), Dagger isn't instantiating the object, you are. Therefore, Dagger doesn't inject the @Inject-annotated fields, because it assumes you want the object exactly as you returned it.

If you want Dagger to populate SignupUseCase, you'll need to do one of the following:

  • Let Dagger create SignupPresenter and receive it in your @Provides method. You'll need to add an @Inject-annotated constructor to SignupPresenter, potentially with no args.

    @FeatureScope
    @Provides
    public static SignupContract.Presenter providePresenter(SignupPresenter presenter) {
      return presenter;
    }
    
  • Let Dagger create SignupPresenter and bind it to SignupContract.Presenter using a @Binds method. This requires the @Inject-annotated constructor on SignupPresenter and also requires making your Module an abstract class.

    @FeatureScope
    @Binds
    abstract SignupContract.Presenter providePresenter(SignupPresenter presenter);
    
  • Use a MembersInjector, which you can get via injection. You probably don't want this one unless you're receiving an instance of SignupPresenter that you can add @Inject methods and fields to, but that Dagger can't create.

    @FeatureScope
    @Provides
    public static SignupContract.Presenter providePresenter(
        MembersInjector<SignupPresenter> injector) {
      SignupPresenter presenter = new SignupPresenter();
      injector.injectMembers(presenter);
      return presenter;
    }
    
Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251
  • Thank you very much!!! Your code work successfully. But I would like to ask some questions to you. I have tried lile this too. (please kindly check my edited Question). But didn't work. Please Explain me about that too. And can you explain me in more details about this sentences. **When you call new SignupPresenter(), Dagger isn't instantiating the object, you are. Therefore, Dagger doesn't inject the @Inject-annotated fields, because it assumes you want the object exactly as you returned it.** . You mean I can't inject other components to an ```@Provides``` annotated class? – pak Mar 24 '22 at 15:56
  • I don't have enough context for your edit; rather than _expanding the scope of your answered question_, please ask a new one, include your error details, and link to this one. For a `@Provides`-annotated class, you _can_ inject other components by requesting them as parameters on the `@Provides` method, the same way I requested `SignupPresenter`; you can do that for dependencies of an object you create, as well. However, Dagger does not assume that you want your @Provides result to be further injected; it assumes you want it as you've returned it. You'll have to use a MembersInjector for that. – Jeff Bowman Mar 24 '22 at 16:16