[英]Android Dynamic Feature modules with Dagger Hilt
I have built a Dynamic feature module sample with Fragments, sub components and dependent components based on plaid app, if you wish to check out here is the link.我已经基于格子应用构建了一个包含片段、子组件和依赖组件的动态功能模块示例,如果您想查看这里是链接。 Now, i'm trying to convert it to Dagger Hilt using the official android document .
现在,我正在尝试使用官方 android 文档将其转换为 Dagger Hilt。
In core module which is the library module, app module and dynamic feature modules depend on在库模块的核心模块中,应用程序模块和动态功能模块依赖于
@Singleton
@Component(modules = [CoreModule::class])
interface CoreComponent {
/*
Provision methods to provide dependencies below to components that depends on
CoreComponent
*/
fun coreDependency(): CoreDependency
fun coreCameraDependency(): CoreCameraDependency
fun corePhotoDependency(): CorePhotoDependency
fun coreActivityDependency(): CoreActivityDependency
@Component.Factory
interface Factory {
fun create(@BindsInstance application: Application): CoreComponent
}
}
and it's module它是模块
@Module(includes = [CoreProvideModule::class])
abstract class CoreModule {
@Binds
abstract fun bindContext(application: Application): Context
}
@Module
object CoreProvideModule {
@Singleton
@Provides
fun provideCoreDependency(application: Application) = CoreDependency(application)
@ActivityScope
@Provides
fun provideCoreActivityDependency(context: Context) = CoreActivityDependency(context)
@Provides
fun provideCoreCameraDependency(): CoreCameraDependency = CoreCameraDependency()
@Provides
fun provideCorePhotoDependency(): CorePhotoDependency = CorePhotoDependency()
}
How is CoreComponent migrated? CoreComponent 是如何迁移的? Do provision methods still stay and i only change
提供方法是否仍然存在,我只会改变
@Singleton
@DefineComponent
or或者
@Singleton
@DefineComponent(parent = ApplicationComponent.class)
for CoreModule i guess i only change对于 CoreModule 我想我只改变
@EntryPoint
@InstallIn(CoreComponent::class)
or is this for adding provision methods in CoreComponent
?或者这是为了在
CoreComponent
中添加提供方法?
How do i create sub-component in app module?如何在应用模块中创建子组件?
If anyone has a sample with dynamic feature fragments and hilt, or tutorial to build, it would be more than welcome.如果有人有一个带有动态特征片段和刀柄的示例,或者要构建的教程,那将是非常受欢迎的。 I'm just working on it at the moment, if i figure it out i would post an answer
我现在正在研究它,如果我弄清楚我会发布答案
I finally figured it out.我终于弄明白了。
For an app structure对于应用程序结构
FeatureCamera FeaturePhotos (Dynamic Feature Modules)
| | |
| ----App
| |
core(android-library)
Camera dynamic feature module dependencies from core module, Photo dynamic feature module dependencies from app.来自核心模块的相机动态特征模块依赖关系,来自应用程序的照片动态特征模块依赖关系。
First create a CoreModule
in library module首先在库模块中创建一个
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()
}
An interface with @EntryPoint
is required to with provision methods defined in this interface, if you don't define a method for that dependency you cannot inject it even though there is a @Provides
method for it.带有
@EntryPoint
的接口需要在此接口中定义提供方法,如果您没有为该依赖项定义方法,即使有@Provides
方法,您也无法注入它。 These are mock dependencies that take application or context as only parameter.这些是将应用程序或上下文作为唯一参数的模拟依赖项。
@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
}
In camera dynamic feature module, create another module for the dependency based inside of this dynamic feature module.在相机动态功能模块中,为基于此动态功能模块内部的依赖关系创建另一个模块。
@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
}
And component
to inject dependencies to Fragments
or Activities
in this DFM.以及向此 DFM 中的
Fragments
或Activities
注入依赖项的component
。
@Component( dependencies = [CoreComponent::class], modules = [CameraModule::class] ) interface CameraComponent { @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
}
} }
If injected to Activity call in onCreate()
如果在
onCreate()
中注入 Activity 调用
DaggerCameraComponent.factory().create(
EntryPointAccessors.fromApplication(
applicationContext,
CoreComponent::class.java
),
application
)
.inject(this)
For injecting to Fragment call in onCreate()
用于在
onCreate()
中注入 Fragment 调用
DaggerCameraComponent.factory().create(
EntryPointAccessors.fromApplication(
requireActivity().applicationContext,
CoreComponent::class.java
),
requireActivity().application
)
.inject(this)
The trick is here to get dependency interface annotated with @EntryPoint
using EntryPointAccessors.fromApplication()
诀窍是使用
EntryPointAccessors.fromApplication()
获得用@EntryPoint
注释的依赖接口
Also created Activity based dependencies in app module还在 app 模块中创建了基于 Activity 的依赖项
MainActivityModule.kt 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
}
And only intend to inject these dependencies to Photos dynamic feature module so named it as PhotoDependencies
并且只打算将这些依赖项注入照片动态功能模块,因此将其命名为
PhotoDependencies
@EntryPoint
@InstallIn(ActivityComponent::class)
interface PhotoModuleDependencies {
fun toastMaker(): ToastMaker
fun mainActivityObject(): MainActivityObject
}
In Photos dynamic feature module create dagger module named PhotoModule
在照片动态功能模块中创建名为
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
}
And component和组件
@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
}
}
And inject to fragments with并注入碎片
DaggerPhotoComponent.factory().create(
EntryPointAccessors.fromActivity(
requireActivity(),
PhotoModuleDependencies::class.java
),
requireActivity().application
)
.inject(this)
The trick here is to get EntryPointAccessors.fromActivity
instead of fromApplication.这里的技巧是获取
EntryPointAccessors.fromActivity
而不是 fromApplication。
You can check out this link if you wish to experiment yourself.如果您想自己进行实验,可以查看此链接。
If you wish to add ViewModel
to dynamic feature modules with hilt you can check out my answer here .如果您希望将
ViewModel
添加到带有刀柄的动态功能模块中,您可以在此处查看我的答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.