java - 使用 ContributesAndroidInjector 提供 Activity
问题描述
我在向Activity
需要此对象的依赖项提供对象时遇到问题。
我有一个非常标准的 Dagger 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.
似乎没有提供该活动,但我不知道为什么。我试图按照其中一个教程进行相同的设置并且可以注入Activity
对象。
我正在使用DaggerApplication
,DaggerAppCompatActivity
和DaggerFragment
.
解决方案
虽然我不确定它如何/为什么会显示您所显示的错误,但您在@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);
}
}
推荐阅读
- javascript - 从 Codesandbox.io 访问 Airtable
- angular - 添加使用 ngfor 迭代对象数组时如何动态添加类名
- postgresql - 如何保存与Gorm的一对一关系?
- python - 如何使用关键字进行模糊搜索并返回匹配的子字符串?
- python - 如何将 df 列 [JSON_Format] 转换为 PySpark 中的多个列?
- oauth-2.0 - 解释 Open ID 连接中的离线令牌验证与在线令牌验证?优势、局限和权衡
- php - Nginx + Php-fpm fastcgi 上游超时
- node.js - React 应用程序无法加载 localhost:3000
- visual-studio - 无法从 VS2017 加载模板到 VS2019
- python - Python Scrapy Crawler - 尝试在 Github 上自动记录问题不起作用 - Gist 无法在 Linux 机器上创建(适用于 Windows)