带有 Kotlin 的 Dagger 2,在 ApplicationComponent 中返回具有泛型的类型

Posted

技术标签:

【中文标题】带有 Kotlin 的 Dagger 2,在 ApplicationComponent 中返回具有泛型的类型【英文标题】:Dagger 2 with Kotlin, returning type with generic in ApplicationComponent 【发布时间】:2017-05-24 19:20:50 【问题描述】:

我想返回泛型类型以由子图公开,问题出在自动生成的 java 类中,我试图做一些事情,但解决它的一种方法是从 AppComponent 中删除泛型类型和返回简单对象。还有更“正确”的方法吗?

这是 AppComponent

@Singleton
@Component(modules = arrayOf(ApplicationModule::class))
interface ApplicationComponent 
    fun inject(activity: BaseActivity<MvpView, MvpPresenter<MvpView>>)

    //...
    fun dataBase(): Database<Realm>

这是 ApplicationModule 中的函数

@Provides @Singleton fun provideDatabase(@AppContext context: App): Database<Realm> 
    Realm.init(context)
    val config = RealmConfiguration.Builder()
            .deleteRealmIfMigrationNeeded()
            .name("db")
            .build()
    Realm.setDefaultConfiguration(config)
    return RealmDatabase(Realm.getDefaultInstance())

那么我想收到我的数据库

@Provides @ActivityScope fun provideDich(database: Database<Realm>) = Someobject(database)

然后我看到日志显示:

**Error:com.test.data.storage.Database<? extends io.realm.Realm> cannot be provided without an @Provides-annotated method.**

因为 dagger2 生成这样的工厂并且有 java 掩码

    public final class Logout_Factory implements Factory<Logout> 
  private final MembersInjector<Logout> logoutMembersInjector;

  private final Provider<SessionStorage.CloudStorage> arg0Provider;

  private final Provider<Database<? extends Realm>> arg1Provider;

  public Logout_Factory(
      MembersInjector<Logout> logoutMembersInjector,
      Provider<SessionStorage.CloudStorage> arg0Provider,
      Provider<Database<? extends Realm>> arg1Provider) 
    assert logoutMembersInjector != null;
    this.logoutMembersInjector = logoutMembersInjector;
    assert arg0Provider != null;
    this.arg0Provider = arg0Provider;
    assert arg1Provider != null;
    this.arg1Provider = arg1Provider;
  

  @Override
  public Logout get() 
    return MembersInjectors.injectMembers(
        logoutMembersInjector, new Logout(arg0Provider.get(), arg1Provider.get()));
  

  public static Factory<Logout> create(
      MembersInjector<Logout> logoutMembersInjector,
      Provider<SessionStorage.CloudStorage> arg0Provider,
      Provider<Database<? extends Realm>> arg1Provider) 
    return new Logout_Factory(logoutMembersInjector, arg0Provider, arg1Provider);
  

【问题讨论】:

【参考方案1】:

我遇到了同样的问题,我找到了解决方案。

您需要在您的@Provide 方法返回类型中声明@JvmWildcard

@Provides 
@Singleton 
fun provideDatabase(@AppContext context: App): Database<@JvmWildcard Realm> 
    Realm.init(context)
    val config = RealmConfiguration.Builder()
            .deleteRealmIfMigrationNeeded()
            .name("db")
            .build()
    Realm.setDefaultConfiguration(config)
    return RealmDatabase(Realm.getDefaultInstance())

【讨论】:

以上是关于带有 Kotlin 的 Dagger 2,在 ApplicationComponent 中返回具有泛型的类型的主要内容,如果未能解决你的问题,请参考以下文章

没有Dagger2的Android Kotlin MVVM结构

kotlin 缺少提供程序的 Dagger 2 错误

Kotlin dagger 2 Android ViewModel 注入错误

更新到 Kotlin 1.3.30 会破坏 Dagger 2.21 的构建

Android kotlin 使用Dagger2报错 InvocationTargetException 不能生成DaggerXXComponent

Kotlin、Java、multidex、Dagger 2、Butterknife 和 Realm:transformClassesWithJarMergingForDebug:重复条目:org/je