我有这个模块:

@Module
public class UserProfileModule {

    @Provides
    @Singleton
    UserProfileController providesUserProfileController() {
        return new UserProfileController();
    }

}

这个部分:
@Component(modules = {UserProfileModule.class})
@Singleton
public interface AppComponent {

    void inject(UserProfileActivity activity);

}

到目前为止,在我的UserProfileActivity中,我可以@InjectanUserProfileController。但现在,我需要将UserProfileActivity注入控制器。我是说,互相注射。
我可以通过在UserProfileControllerUserProfileActivity中调用一个setActivity(this);setter来完成,但是如果可以自动的话就更好了。
怎样才能做到这一点?
谢谢。

最佳答案

对于初学者:将其添加到构造函数中。然后声明依赖关系。

@Provides
@Singleton
UserProfileController providesUserProfileController(UserProfileActivity activity) {
    return new UserProfileController(activity);
}

在这样做之后,Dagger将抱怨无法提供UserProfileActivity,除非您已经这样做了。如果没有,请添加另一个模块,或者只提供来自同一个模块的依赖项。实际实现如下,首先我们需要修复您的代码。
@Singleton是层次结构顶部的依赖项。您不能,或者至少不应该对带注释的对象有活动依赖关系,因为这可能会导致臭味和/或内存泄漏。引入自定义作用域@Singleton以用于活动生命周期内的依赖项。
@Scope
@Retention(RUNTIME)
public @interface PerActivity {}

这将允许对象的正确作用域。也请参考一些关于匕首的教程,因为这是一个非常重要的问题,在一个单一的答案涵盖一切将是太多。例如Tasting dagger 2 on android
以下通过扩展模块使用上述两个选项的后一种方法:
@Module
public class UserProfileModule {

    private final UserProfileActivity mActivity;

    public UserProfileModule(UserProfileActivity activity) {
        mActivity = activity;
    }

    @Provides
    @PerActivity
    UserProfileActivity provideActivity() {
        return mActivity;
    }

    @Provides // as before
    @PerActivity
    UserProfileController providesUserProfileController(UserProfileActivity  activity) {
        return new UserProfileController(activity);
    }

}

如果现在使用组件@PerActivity,则可以用活动作为参数创建模块的新实例。然后将正确提供依赖项。

10-08 13:20