繁体   English   中英

Android 带匕首刀柄的动态功能模块

[英]Android Dynamic Feature modules with Dagger Hilt

我已经基于格子应用构建了一个包含片段、子组件和依赖组件的动态功能模块示例,如果您想查看这里是链接。 现在,我正在尝试使用官方 android 文档将其转换为 Dagger Hilt。

在库模块的核心模块中,应用程序模块和动态功能模块依赖于

@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
    }

}

它是模块

@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()

}

CoreComponent 是如何迁移的? 提供方法是否仍然存在,我只会改变

@Singleton
@DefineComponent

或者

@Singleton
@DefineComponent(parent = ApplicationComponent.class)

对于 CoreModule 我想我只改变

@EntryPoint
@InstallIn(CoreComponent::class)

或者这是为了在CoreComponent中添加提供方法?

如何在应用模块中创建子组件?

如果有人有一个带有动态特征片段和刀柄的示例,或者要构建的教程,那将是非常受欢迎的。 我现在正在研究它,如果我弄清楚我会发布答案

我终于弄明白了。

对于应用程序结构

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
}

以及向此 DFM 中的FragmentsActivities注入依赖项的component

@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
}

}

如果在onCreate()中注入 Activity 调用

  DaggerCameraComponent.factory().create(
            EntryPointAccessors.fromApplication(
                    applicationContext,
                    CoreComponent::class.java
            ),
            application
    )
            .inject(this)

用于在onCreate()中注入 Fragment 调用

DaggerCameraComponent.factory().create(
        EntryPointAccessors.fromApplication(
                requireActivity().applicationContext,
                CoreComponent::class.java
        ),
        requireActivity().application
)
        .inject(this)

诀窍是使用EntryPointAccessors.fromApplication()获得用@EntryPoint注释的依赖接口

还在 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
}

在照片动态功能模块中创建名为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添加到带有刀柄的动态功能模块中,您可以在此处查看我的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM