带有Dagger Hilt的Android动态功能模块 [英] Android Dynamic Feature modules with Dagger Hilt

查看:388
本文介绍了带有Dagger Hilt的Android动态功能模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您想查看官方android将其转换为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.

在作为库模块的核心模块中,应用程序模块和动态功能模块取决于

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
    }

}

及其模块

@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如何迁移?设置方法是否仍然存在,我只会改变

How is CoreComponent migrated? Do provision methods still stay and i only change

@Singleton
@DefineComponent

@Singleton
@DefineComponent(parent = ApplicationComponent.class)

对于CoreModule,我想我只会改变

for CoreModule i guess i only change

@EntryPoint
@InstallIn(CoreComponent::class)

或者这是在CoreComponent中添加供应方法的方法?

or is this for adding provision methods in 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

推荐答案

我终于知道了.

对于应用结构

FeatureCamera  FeaturePhotos  (Dynamic Feature Modules)  
|         |    |
|         ----App
|              |
core(android-library)

来自核心模块的相机动态功能模块依赖性,来自应用程序的照片动态功能模块依赖性.

Camera dynamic feature module dependencies from core module, Photo dynamic feature module dependencies from app.

首先在库模块中创建一个CoreModule

First create a CoreModule in library module

@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方法,也无法注入它.这些是模拟依赖,仅将应用程序或上下文作为参数.

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

component将依赖项注入此DFM中的FragmentsActivities.

And component to inject dependencies to Fragments or Activities in this DFM.

@Component( 依赖= [CoreComponent :: class], 模块= [CameraModule :: class] ) 接口CameraComponent {

@Component( dependencies = [CoreComponent::class], modules = [CameraModule::class] ) interface 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()

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

用于在onCreate()

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

技巧是在这里获得用@EntryPoint注释的依赖接口 使用EntryPointAccessors.fromApplication()

The trick is here to get dependency interface annotated with @EntryPoint using EntryPointAccessors.fromApplication()

还在应用程序模块中创建了基于活动的依赖项

Also created Activity based dependencies in app module

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

}

并且仅打算将这些依赖项注入到Photos动态功能模块中,因此将其命名为PhotoDependencies

And only intend to inject these dependencies to Photos dynamic feature module so named it as PhotoDependencies

@EntryPoint
@InstallIn(ActivityComponent::class)
interface PhotoModuleDependencies {

    fun toastMaker(): ToastMaker

    fun mainActivityObject(): MainActivityObject
}

在照片"动态功能模块中,创建名为PhotoModule

In Photos dynamic feature module create dagger module named 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.

The trick here is to get EntryPointAccessors.fromActivity instead of fromApplication.

您可以查看此链接,如果您想尝试一下自己.

You can check out this link if you wish to experiment yourself.

这篇关于带有Dagger Hilt的Android动态功能模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆