0

I am implementing an MVP in android. I'm using dagger and for some unknown reason, or lack of knowledge, do not get injected into another class .

I have this module:

@Module(
        injects = {
                LoginActivity.class,
        },
        library = true,
        complete = false
)
public class LoginModule {
    private LoginActivity loginActivity;

    public LoginModule(LoginActivity loginActivity) {
        this.loginActivity = loginActivity;
    }

    @Provides
    @Singleton
    LoginPresenter provideLoginPresenter() {
        return new LoginPresenterImpl(loginActivity);
    }

    @Provides @Singleton
    public UrlService provideUrlService(){
        return new UrlServiceImpl();
    }

}

This activity:

public class LoginActivity extends BaseActivity implements LoginView {
    @Inject
    public LoginPresenter loginPresenter;
    @Inject
    UrlService urlService;
    //...
    @Override
    protected List<Object> getModules() {
        List<Object> modules = new LinkedList<Object>();
        modules.add(new LoginModule(this));
        return modules;
    }
    //...
    //I use butterknife too
    @Optional
    @OnClick(R.id.btn_login_accept)
    public void testButtonOnClick() {
        disableAccept();
        writeLog(urlService.getLoginUrl()); //This UrlService works fine.
        loginPresenter.login();             //And login presenter works too.

    }

and this code injection LoginPresenter where UrlService returns a NullPointerException

public class LoginPresenterImpl extends BasePresenterImpl<LoginView> 
                  implements LoginPresenter {
    @Inject
    public LoginPresenterImpl(LoginView view) {
        super(view);
    }

    @Inject
    public UrlService urlService;

    @Override
    public void login() {
        view.showShortMessage(urlService.getLoginUrl());//throws nullpointerexception

Please could someone help me ?

thanks in advance

  • You don't include your `onCreate()` method, I am assuming you are calling `inject(this)` as part of it though? – Phil H Dec 16 '14 at 13:05

2 Answers2

0

You never inject your UrlService instance into your LoginPresenterImpl.

The (arguably) best way to solve your problem is to supply it to your constructor like this:

public class LoginPresenterImpl extends BasePresenterImpl<LoginView> 
                  implements LoginPresenter {

    private UrlService urlService;

    public LoginPresenterImpl(LoginView view, UrlService urlService) {
        super(view);
        this.urlService = urlService;
    }

    @Override
    public void login() {
        view.showShortMessage(urlService.getLoginUrl());
    }
}

Then change your module to:

@Provides
@Singleton
LoginPresenter provideLoginPresenter(UrlService urlService) {
    return new LoginPresenterImpl(loginActivity, urlService);
}

Note that you don't need the @Inject annotation on your LoginPresenterImpl constructor, as you're instantiating it yourself.

nhaarman
  • 98,571
  • 55
  • 246
  • 278
0

In addition to my other answer, this answer uses a different approach, namely by letting Dagger instantiate your LoginPresenter class:

public class LoginPresenterImpl extends BasePresenterImpl<LoginView> 
                  implements LoginPresenter {

    private UrlService urlService;

    @Inject
    public LoginPresenterImpl(LoginView view, UrlService urlService) {
        super(view);
        this.urlService = urlService;
    }

    @Override
    public void login() {
        view.showShortMessage(urlService.getLoginUrl());
    }
}

Change your module to:

@Provides 
@Singleton
public UrlService provideUrlService(){
    return new UrlServiceImpl();
}

@Provides
public LoginView provideLoginView() {
    return loginActivity;
}

@Provides
@Singleton
LoginPresenter provideLoginPresenter(LoginPresenterImp loginPresenter) {
    return loginPresenter;
}

Note that now you do need the @Inject annotation to your LoginPresenterImpl constructor.

nhaarman
  • 98,571
  • 55
  • 246
  • 278