代码之家  ›  专栏  ›  技术社区  ›  user3448282

使用贡献者和参与者提供活动

  •  0
  • user3448282  · 技术社区  · 6 年前

    我无法提供 Activity 需要此对象的依赖项。

    我用匕首2.13有一个相当标准的设置,如下所示:

    AppComponent.java

    @Singleton
    @Component(modules = {
            AndroidInjectionModule.class,
            AppModule.class,
            ActivityModule.class
    })
    public interface AppComponent extends AndroidInjector<Appname> {
        @Component.Builder
        interface Builder {
            @BindsInstance
            Builder application(Appname appname);
            AppComponent build();
        }
    
        void inject(Appname appname);
    }
    

    ActivityModule.java

    @Module
    abstract public class ActivityModule {
        @ContributesAndroidInjector(modules = {MainActivityModule.class, MainActivityFragmentsModule.class})
        abstract MainActivity contributeMainActivity();
    }
    

    MainActivityModule.java

    @Module
    public class MainActivityModule {
    
    @Provides
    @Singleton
    static Billing provideBilling(Context context) {
        return new Billing(context);
    }
    
    @Provides
    @Singleton
    static ActivityCheckout provideActivityCheckout(MainActivity activity, Billing billing) {
        return ActivityCheckout.forActivity(activity, billing);
    }
    }
    

    MainActivityFragmentsModule.java

    @Module
    abstract public class MainActivityFragmentsModule {
        @ContributesAndroidInjector
        abstract WelcomeFragment contributeWelcomeFragment();
    }
    

    当我试图使用 ActivityCheckout 在里面 WelcomeFragment 我有个错误,不能提供这种依赖关系:

    Error:(20, 8) error: [dagger.android.AndroidInjector.inject(T)] org.solovyev.android.checkout.ActivityCheckout cannot be provided without an @Inject constructor or from an @Provides-annotated method.

    似乎没有提供活动,但我不知道为什么。我试图遵循其中的一个教程,其中有相同的设置,可以注入 活动 对象。

    我在用 DaggerApplication ,请 DaggerAppCompatActivity DaggerFragment .

    1 回复  |  直到 6 年前
        1
  •  3
  •   Jeff Bowman    6 年前

    虽然我不确定它将如何/为什么显示您显示的错误,但您在@singleton范围内错误地注册了活动范围内的内容。请注意,您发布的错误消息抱怨没有提供ActivityCheckout;如果无法提供您的活动,您可能会发现一条错误消息,说明没有MainActivity。

    我的预感是您的编译中存在多个错误,但您只发布了最后一个错误,而前面的错误表明您不能将@singleton绑定安装到@contributesandroidinjector默认创建的未划分的子组件中。因此,Dagger忽略了@provides方法,得到了错误。

    @Provides
    @Singleton  // BAD: If this is Singleton, it will outlive and leak MainActivity.
                // Dagger will complain about mismatched scopes, but it's right:
                // It doesn't make sense for ActivityCheckout to be @Singleton.
    static ActivityCheckout provideActivityCheckout(
        MainActivity activity, Billing billing) {
      return ActivityCheckout.forActivity(activity, billing);
    }
    

    相反,创建一个特定于活动的范围,它指示每个活动都有自己的范围。

    @Retention(RetentionPolicy.RUNTIME)    // Not used at runtime, but JSR-330
    @Scope                                 // requires that @Scopes are kept at RUNTIME.
    public @interface ActivityScope {}     // PerActivity is also a good name.
    

    现在用它标记您的@contributesandroidinjector,这样您生成的子组件就具有这个范围:

    @ContributesAndroidInjector(
        modules = {MainActivityModule.class, MainActivityFragmentsModule.class})
    @ActivityScope
    abstract MainActivity contributeMainActivity();
    

    以及您的绑定,因此它们与活动组件的生命周期相匹配:

    @Module public class MainActivityModule {
      // I'm assuming this is actually activity scoped, but if it's truly singleton,
      // leave it @Singleton and move it to AppModule.
      @Provides
      @ActivityScope
      static Billing provideBilling(Context context) {
        return new Billing(context);
      }
    
      @Provides
      @ActivityScope
      static ActivityCheckout provideActivityCheckout(
          MainActivity activity, Billing billing) {
        return ActivityCheckout.forActivity(activity, billing);
      }
    }