我正在调查我当前Android应用程序中的动态功能模块。
我的应用程序由一个App、多个静态模块和一个动态特性模块组成。
我试图将动态特性模块中声明的存储库类注入我的一个静态模块中的存储库类。
我有一个公共共享模块,它包含一个接口,它定义了
我的动态功能模块有一个类似于以下内容的存储库类:-
class DynamicFeatureRepository @Inject constructor(private val applicationContext: Context) : MyExperimentable {
override fun accessDynamicModuleRawData(): List<MyExperimentDO> {
val myExperimentDOs = mutableListOf<MyExperimentDO>()
applicationContext.resources.openRawResource(R.raw.data).use {
val reader = BufferedReader(InputStreamReader(it))
while (reader.ready()) {
val columns = reader.readLine().split(",")
myExperimentDOs.add(
MyExperimentDO(
myExperimentId = columns[0].toLong(),
selected = columns[1].toBoolean(),
myExperimentName = columns[2],
myExperiment = columns[3]
)
)
}
}
return myExperimentDOs
}
override fun generate(data: String): Map<String, String> {
return emptyMap()
}
}我有另一个使用上述动态特性模块存储库的静态模块
我相信Dagger子组件将允许我将这个动态特性模块存储库注入到我的静态模块类中,但是我不知道如何实现这一点。
到目前为止,我在我的公共模块中声明了以下Dagger类:
import dagger.Module
import dagger.Subcomponent
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
@Subcomponent
interface MyExperimentComponent {
fun inject(myExperimentable: MyExperimentable)
@Subcomponent.Factory
interface Factory {
fun create(): MyExperimentComponent
}
}
@InstallIn(SingletonComponent::class)
@Module(subcomponents = [MyExperimentComponent::class])
class SubcomponentsModule {}在我的动态功能模块中,我有一个匕首类:-
@InstallIn(SingletonComponent::class)
@Module
class ExperimentModule() {
@Provides
fun getMyExperiment(@ApplicationContext appContext: Context): MyExperimentable {
return DynamicFeatureRepository(appContext)
}
}在我的静态模块中,我有一个@Inject
@Inject
lateinit var myExperimentable: MyExperimentable我的应用程序构建并运行,但是我的静态模块中的@Inject并不满足,因为我的应用程序失败了
kotlin.UninitializedPropertyAccessException: lateinit property myExperimentable has not been initialized我哪里出错了?
如何@为我的一个静态模块提供动态功能模块repo
以下是我的静态模块中的“注入站点”:
class MyRepository @Inject constructor(private val datastore: DataStore, private val workMonitor: WorkMonitor) {
@Inject
lateinit var myExperimentable: MyExperimentable
...
fun accessDynamicModuleRawData() {
val rawData = myExperimentable.accessDynamicModuleRawData()
Timber.i("xxx ${rawData.size}")
}
}在Android文档中有一个突出显示的注释:-
注意:每当您想要创建ApplicationComponent的子组件时,都会发生此问题。如果需要创建依赖于功能模块的常规分级模块,并且需要创建依赖于该功能模块中定义的组件的组件,则可以像往常一样使用子组件。
这不是我的案子吗?我的静态模块需要/依赖于在动态特性模块中定义的组件。这个评论让我相信我可以使用Dagger子组件来解决我的问题。如果这是真的,“如何”使用子组件来启用将我的DFM回购注入我的静态模块回购?
更新
我已将此@EntryPoint添加到我的应用程序模块中:-
@EntryPoint
@InstallIn(SingletonComponent::class)
interface MyExperimentableEntryPointInterface {
fun getMyExperimentable(): MyExperimentable
}这将允许我在我的目标库中使用这个
val bar = EntryPoints.get(appContext, MyExperimentableEntryPointInterface::class.java).getMyExperimentable()我遇到的问题是如何从DFM中"Provide“MyExperimentable的实现。
在我的DFM中,我试过这样做:-
@Module
@DisableInstallInCheck
object DynamicFeatureRepositoryeModule {
@Provides
@Singleton
fun provideDynamicFeatureRepository(): MyExperimentable {
return DynamicFeatureRepository()
}
}然而,我在构建时得到了这个异常:-
error: [Dagger/MissingBinding] MyExperimentable cannot be provided without an @Provides-annotated method.在我的应用程序中提供DFM存储库的实例时,我遗漏了什么?
更新解决方案
我设法使用Dagger实现了想要的结果,并将我的解决方案建立在这个示例上--我不喜欢这个方面--尽管这是使用反射的
发布于 2021-02-24 19:23:31
为什么不在MyExperimentable类中添加MyRepository依赖项作为构造函数注入。通常,我们为活动/视图/片段进行字段注入。如果我们使用构造函数注入来完成它,那么您将在编译期间得到确切的错误原因。
愿这样的事情:
class MyRepository @Inject constructor(private val datastore: DataStore, private val workMonitor: WorkMonitor, private val myExperimentable: MyExperimentable) {
//@Inject
//lateinit var myExperimentable: MyExperimentable
...
fun accessDynamicModuleRawData() {
val rawData = myExperimentable.accessDynamicModuleRawData()
Timber.i("xxx ${rawData.size}")
}
}https://stackoverflow.com/questions/66336398
复制相似问题