我终于弄明白了。
对于应用程序结构
FeatureCamera FeaturePhotos (Dynamic Feature Modules)
| | |
| ----App
| |
core(android-library)
来自核心模块的相机动态特征模块依赖关系,来自应用程序的照片动态特征模块依赖关系。
首先创建一个CoreModule
库模块
@InstallIn(ApplicationComponent::class)
@Module
class CoreModule {
@Singleton
@Provides
fun provideCoreDependency(application: Application) = CoreDependency(application)
@Provides
fun provideCoreActivityDependency(context: Application) = CoreActivityDependency(context)
@Provides
fun provideCoreCameraDependency(): CoreCameraDependency = CoreCameraDependency()
@Provides
fun provideCorePhotoDependency(): CorePhotoDependency = CorePhotoDependency()
}
在此接口中定义的提供方法需要一个@EntryPoint
接口,如果您没有为该依赖项定义一个方法,即使有一个@Provides
方法,您也无法注入它。这些是将应用程序或上下文作为唯一参数的模拟依赖项。
@EntryPoint
@InstallIn(ApplicationComponent::class)
interface CoreComponent {
/*
Provision methods to provide dependencies to components that depend on this component
*/
fun coreDependency(): CoreDependency
fun coreActivityDependency(): CoreActivityDependency
fun coreCameraDependency(): CoreCameraDependency
fun corePhotoDependency(): CorePhotoDependency
}
在相机动态功能模块中,为基于此动态功能模块内部的依赖关系创建另一个模块。
@InstallIn(FragmentComponent::class)
@Module(includes = [CameraBindModule::class])
class CameraModule {
@Provides
fun provideCameraObject(context: Context) = CameraObject(context)
}
@InstallIn(FragmentComponent::class)
@Module
abstract class CameraBindModule {
@Binds
abstract fun bindContext(application: Application): Context
}
并将component
依赖项注入此 DFMFragments
或其中Activities
。
@Component( 依赖项 = [CoreComponent::class], 模块 = [CameraModule::class] ) 接口 CameraComponent {
fun inject(cameraFragment1: CameraFragment1)
fun inject(cameraFragment2: CameraFragment2)
fun inject(cameraActivity: CameraActivity)
@Component.Factory
interface Factory {
fun create(coreComponent: CoreComponent, @BindsInstance application: Application): CameraComponent
}
}
如果注入到 Activity 调用中onCreate()
DaggerCameraComponent.factory().create(
EntryPointAccessors.fromApplication(
applicationContext,
CoreComponent::class.java
),
application
)
.inject(this)
用于注入 Fragment 调用onCreate()
DaggerCameraComponent.factory().create(
EntryPointAccessors.fromApplication(
requireActivity().applicationContext,
CoreComponent::class.java
),
requireActivity().application
)
.inject(this)
诀窍是在这里获得@EntryPoint
使用注释的依赖接口EntryPointAccessors.fromApplication()
还在 app 模块中创建了基于 Activity 的依赖项
MainActivityModule.kt
@InstallIn(ActivityComponent::class)
@Module(includes = [MainActivityBindModule::class])
class MainActivityModule {
@Provides
fun provideToastMaker(application: Application) = ToastMaker(application)
@ActivityScoped
@Provides
fun provideMainActivityObject(context: Context) = MainActivityObject(context)
}
@InstallIn(ActivityComponent::class)
@Module
abstract class MainActivityBindModule {
@Binds
abstract fun bindContext(application: Application): Context
}
并且只打算将这些依赖项注入照片动态功能模块,因此将其命名为PhotoDependencies
@EntryPoint
@InstallIn(ActivityComponent::class)
interface PhotoModuleDependencies {
fun toastMaker(): ToastMaker
fun mainActivityObject(): MainActivityObject
}
在 Photos 动态功能模块中创建名为 dagger 的模块PhotoModule
@InstallIn(FragmentComponent::class)
@Module(includes = [PhotoBindModule::class])
class PhotoModule {
@Provides
fun providePhotoObject(application: Application): PhotoObject = PhotoObject(application)
}
@InstallIn(FragmentComponent::class)
@Module
abstract class PhotoBindModule {
@Binds
abstract fun bindContext(application: Application): Context
}
和组件
@Component(
dependencies = [PhotoModuleDependencies::class],
modules = [PhotoModule::class]
)
interface PhotoComponent {
fun inject(photosFragment1: PhotoFragment1)
fun inject(photosFragment2: PhotoFragment2)
@Component.Factory
interface Factory {
fun create(photoModuleDependencies: PhotoModuleDependencies,
@BindsInstance application: Application): PhotoComponent
}
}
并注入碎片
DaggerPhotoComponent.factory().create(
EntryPointAccessors.fromActivity(
requireActivity(),
PhotoModuleDependencies::class.java
),
requireActivity().application
)
.inject(this)
这里的诀窍是获取EntryPointAccessors.fromActivity
而不是 fromApplication。
如果您想自己进行实验,可以查看此链接。
如果您希望ViewModel
使用刀柄添加到动态功能模块,您可以在此处查看我的答案。