需要用匕首进行嵌套注射

时间:2014-12-14 16:17:37

标签: android dagger

我在android中实现了一个MVP。 我正在使用匕首,由于某些未知原因,或缺乏知识,不要注入另一个班级。

我有这个模块:

@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();
    }

}

此活动:

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.

    }

此代码注入LoginPresenter,其中UrlService返回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

请有人帮帮我吗?

提前致谢

2 个答案:

答案 0 :(得分:0)

您永远不会将UrlService个实例注入LoginPresenterImpl

解决问题的(可以说)最好的方法是将它提供给你的构造函数:

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());
    }
}

然后将模块更改为:

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

请注意,您不需要在@Inject构造函数上使用LoginPresenterImpl注释,因为您自己实例化它。

答案 1 :(得分:0)

除了我的另一个答案,这个答案使用了一种不同的方法,即让Dagger实例化你的LoginPresenter类:

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());
    }
}

将模块更改为:

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

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

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

请注意,现在您执行需要@Inject构建函数的LoginPresenterImpl注释。