Android 匕首2绑定错误
我正在开发一个多数据库应用程序,它可以在任何时候实例化,而不仅仅是在应用程序启动时 我创建了一个子计算机“LoggedInComponent”,每当应用程序需要使用数据库时,都需要创建它。数据库被注入到数据源中,存储库被注入到用例中,用例被注入到viewModel中,当数据库直接注入到viewModel中时,构建成功,但如果尝试将其注入到数据源中,Gradle构建失败,并出现以下错误: java.lang.IllegalArgumentException:找不到BindingRequest{key=com.xxxxx.app.framework.database.database的表达式,requestKind=Optional[PROVIDER],frameworkType=Optional[PROVIDER]} 谢谢 应用程序组件Android 匕首2绑定错误,android,kotlin,dagger-2,Android,Kotlin,Dagger 2,我正在开发一个多数据库应用程序,它可以在任何时候实例化,而不仅仅是在应用程序启动时 我创建了一个子计算机“LoggedInComponent”,每当应用程序需要使用数据库时,都需要创建它。数据库被注入到数据源中,存储库被注入到用例中,用例被注入到viewModel中,当数据库直接注入到viewModel中时,构建成功,但如果尝试将其注入到数据源中,Gradle构建失败,并出现以下错误: java.lang.IllegalArgumentException:找不到BindingRequest{ke
@ApplicationScope @Component(
modules = [
AndroidSupportInjectionModule::class,
AndroidInjectionModule::class,
ApplicationModule::class,
ActivityBuilder::class,
FragmentBuilder::class
] ) interface ApplicationComponent : AndroidInjector<Altagem> {
@Component.Factory
abstract class Factory : AndroidInjector.Factory<Altagem> {
abstract override fun create(@BindsInstance instance: Altagem): ApplicationComponent
}
fun activityInjector(): DispatchingAndroidInjector<Activity>
val loggedInComponentFactory: LoggedInComponent.Factory
val loggedInComponentManager: LoggedInComponentManager
}
@LoggedInScope @Subcomponent(modules =
[LoggedInActivityBuilder::class, DatabaseModule::class]) interface
LoggedInComponent {
@Subcomponent.Factory
interface Factory {
fun create(): LoggedInComponent
}
fun activityInjector(): DispatchingAndroidInjector<Activity>
}
UseCaseModule
@Module
class DatabaseModule {
@Provides
@LoggedInScope
fun provideDatabase(
@ApplicationContext context: Context, @DatabaseFile databaseFile: File,
isInitialized
: Boolean
): Database =
if (isInitialized)
DatabaseBuilder.build(context)
else
DatabaseBuilder.build(context, databaseFile)
@Provides
@DatabaseFile
@LoggedInScope
fun provideDatabaseFile(fileManager: FileManager): File {
return fileManager.getFileFromInternalCache(DATABASE_FILE_NAME)
}
@Provides
@LoggedInScope
fun provideIsInitialized(appConfigurationFile: AppConfigurationFile) = true
/*appConfigurationFile.getAppConfiguration().isDatabaseInitialized*/
}
@Module(includes = [RepositoryModule::class])
abstract class UseCaseModule {
@Binds
abstract fun bindsGetReportSheetsUseCase(useCase: GetReportSheetsUseCaseImpl): GetReportSheetsUseCase
}
@Module(includes = [DataSourcesModule::class])
abstract class RepositoryModule {
@Binds
abstract fun bindsReportSheetRepository(repository: ReportSheetRepositoryImpl): ReportSheetRepository
}
@Module
abstract class DataSourcesModule {
@Binds
abstract fun bindsReportSheetDatabase(database: ReportSheetDatabaseImpl): ReportSheetDatabase
}
存储模块
@Module
class DatabaseModule {
@Provides
@LoggedInScope
fun provideDatabase(
@ApplicationContext context: Context, @DatabaseFile databaseFile: File,
isInitialized
: Boolean
): Database =
if (isInitialized)
DatabaseBuilder.build(context)
else
DatabaseBuilder.build(context, databaseFile)
@Provides
@DatabaseFile
@LoggedInScope
fun provideDatabaseFile(fileManager: FileManager): File {
return fileManager.getFileFromInternalCache(DATABASE_FILE_NAME)
}
@Provides
@LoggedInScope
fun provideIsInitialized(appConfigurationFile: AppConfigurationFile) = true
/*appConfigurationFile.getAppConfiguration().isDatabaseInitialized*/
}
@Module(includes = [RepositoryModule::class])
abstract class UseCaseModule {
@Binds
abstract fun bindsGetReportSheetsUseCase(useCase: GetReportSheetsUseCaseImpl): GetReportSheetsUseCase
}
@Module(includes = [DataSourcesModule::class])
abstract class RepositoryModule {
@Binds
abstract fun bindsReportSheetRepository(repository: ReportSheetRepositoryImpl): ReportSheetRepository
}
@Module
abstract class DataSourcesModule {
@Binds
abstract fun bindsReportSheetDatabase(database: ReportSheetDatabaseImpl): ReportSheetDatabase
}
数据源模块
@Module
class DatabaseModule {
@Provides
@LoggedInScope
fun provideDatabase(
@ApplicationContext context: Context, @DatabaseFile databaseFile: File,
isInitialized
: Boolean
): Database =
if (isInitialized)
DatabaseBuilder.build(context)
else
DatabaseBuilder.build(context, databaseFile)
@Provides
@DatabaseFile
@LoggedInScope
fun provideDatabaseFile(fileManager: FileManager): File {
return fileManager.getFileFromInternalCache(DATABASE_FILE_NAME)
}
@Provides
@LoggedInScope
fun provideIsInitialized(appConfigurationFile: AppConfigurationFile) = true
/*appConfigurationFile.getAppConfiguration().isDatabaseInitialized*/
}
@Module(includes = [RepositoryModule::class])
abstract class UseCaseModule {
@Binds
abstract fun bindsGetReportSheetsUseCase(useCase: GetReportSheetsUseCaseImpl): GetReportSheetsUseCase
}
@Module(includes = [DataSourcesModule::class])
abstract class RepositoryModule {
@Binds
abstract fun bindsReportSheetRepository(repository: ReportSheetRepositoryImpl): ReportSheetRepository
}
@Module
abstract class DataSourcesModule {
@Binds
abstract fun bindsReportSheetDatabase(database: ReportSheetDatabaseImpl): ReportSheetDatabase
}
ReportSheetDatabaseImpl
class ReportSheetDatabaseImpl @Inject constructor(
private val database: Database // Build fail when trying to inject db here
) : ReportSheetDatabase {
override fun getReportSheetsByReportId(reportId: String): Flow<List<ReportSheet>> = emptyFlow()
}
class ReportSheetRepositoryImpl @Inject constructor(
private val reportSheetDatabase: ReportSheetDatabase
) : ReportSheetRepository {
override fun getReportSheetsById(reportId: String): Flow<List<ReportSheet>> =
reportSheetDatabase.getReportSheetsByReportId(reportId)
}
class GetReportSheetsUseCaseImpl @Inject constructor(
private val reportSheetRepository: ReportSheetRepository
): GetReportSheetsUseCase {
override fun invoke(reportId: String): Flow<List<ReportSheet>> =
reportSheetRepository.getReportSheetsById(reportId)
}
class ReportViewModel @Inject constructor(
app: Altagem,
private val getReportSheetsUseCase: GetReportSheetsUseCase
/*, database: Database // build succeed if database injected here */
) : BaseViewModel(app) {
}
LoggedInActivityBuilder
@Module
abstract class LoggedInActivityBuilder{
@ActivityScope
@ContributesAndroidInjector(modules = [HomeModule::class, FragmentBuilder::class])
abstract fun contributesHomeActivity(): HomeActivity
@ActivityScope
@ContributesAndroidInjector(modules = [InfoModule::class,FragmentBuilder::class])
abstract fun contributesInfoActivity(): InfoActivity
}
@Module
abstract class FragmentBuilder {
@FragmentScope
@ContributesAndroidInjector(modules = [ReportModule::class])
abstract fun contributeReportFragment(): ReportFragment
}
碎片生成器
@Module
abstract class LoggedInActivityBuilder{
@ActivityScope
@ContributesAndroidInjector(modules = [HomeModule::class, FragmentBuilder::class])
abstract fun contributesHomeActivity(): HomeActivity
@ActivityScope
@ContributesAndroidInjector(modules = [InfoModule::class,FragmentBuilder::class])
abstract fun contributesInfoActivity(): InfoActivity
}
@Module
abstract class FragmentBuilder {
@FragmentScope
@ContributesAndroidInjector(modules = [ReportModule::class])
abstract fun contributeReportFragment(): ReportFragment
}
应用程序类
class App : Application(), HasAndroidInjector {
private lateinit var appComponent: ApplicationComponent
override fun onCreate() {
super.onCreate()
appComponent = initAppComponent()
}
private fun initAppComponent() = DaggerApplicationComponent
.factory()
.create(this)
.apply { inject(this@App) }
override fun androidInjector(): AndroidInjector<Any> {
fun injectActivity(activity: BaseActivity) {
if (activity.isDatabaseSubComponent)
appComponent
.loggedInComponentManager
.getComponent().activityInjector()
.inject(activity)
else
appComponent.activityInjector().inject(activity)
}
return AndroidInjector { injected ->
when (injected) {
is BaseActivity -> injectActivity(injected)
else -> {
}
}
}
}
}