【问题标题】:Hilt injected adapter via builder is null通过构建器注入的 Hilt 适配器为空
【发布时间】:2020-07-04 11:49:49
【问题描述】:

我是 dagger 和 hilt 的新手,我正在尝试使用 Hilt 使用构建器将我的适配器注入到我的片段中(片段实际上是在片段寻呼机适配器中,因此它和适配器有多个实例) ,似乎设置正确,我在 onCreate 中的 super 之前构建了组件,但是当稍后尝试在片段中访问它时适配器为空,我想知道以后是否需要以某种方式提供它,例如我有我的适配器我的片段

@AndroidEntryPoint
public class CardHolderFragment extends Fragment {

    public CardAdapter cardAdapter;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    DaggerCardAdapterComponent.builder()
            .cardAdapterDependencies(() -> layoutIdentifier)
            .build().inject(this);
    super.onCreate(savedInstanceState);
    cardAdapter.notifyDataSetChanged(); // CardAdapter.notifyDataSetChanged()' on a null object reference

所以我的问题是,如果组件设置正确,这应该可以工作还是我错过了一个步骤? 我想做的是类似于 cardAdapter = DaggerCardAdapterComponent.getCardAdapter 但我不能在组件中放置提供方法,我查看了匕首迁移指南here 这对我来说有点复杂,因为我只有一个在切换到刀柄之前用匕首几周,但指南提到

最后,如果针对不同的活动或片段组件进行了不同的配置,您可能需要重新设计一些东西。例如,您可以在 Activity 上使用新接口来提供对象。

所以我尝试了这个,这让我实现了接口,然后返回了一个卡适配器,但我不确定我应该在这里返回什么,欢迎任何帮助

这是我的卡适配器组件

@Component(dependencies = CardAdapterDependencies.class, modules = {TypeFactoryModule.class, 
ItemTouchListenerModule.class, GlideModule.class})

public interface CardAdapterComponent {

void inject(CardHolderFragment cardHolderFragment);

@Component.Builder
interface Builder {
    Builder cardAdapterDependencies(CardAdapterDependencies cardAdapterDependencies);
    CardAdapterComponent build();
}

interface HasCardAdapter{
    CardAdapter getCardAdapter();
}
} 

这是我的卡适配器构造函数

@Inject
public CardAdapter(
        ItemTouchListener onItemTouchListener,
        String layoutIdentifier,
        TypeFactory typeFactory,
        RequestManager glide
) {
    this.onItemTouchListener = onItemTouchListener;
    this.typeFactory = typeFactory;
    this.layoutIdentifier = layoutIdentifier;
    this.glide = glide;
    this.elements = new ArrayList<>();
}

【问题讨论】:

  • 适配器应该用@Inject标记为@Inject public CardAdapter cardAdapter。要使用 hilt,您应该使用 @AndroidEntryPoint 以及容器活动标记您的片段,然后删除手动组件注入。 (我假设您的模块配置正确)
  • 我尽快试试这个,让你知道
  • 你的 Fragmentandroidx.Fragment 吗?
  • yh 它是一个 androidx.Fragment
  • @Pavneet_Singh 你明白我在这里使用构建器吗?因为它需要运行时参数

标签: android android-fragments dependency-injection dagger-hilt


【解决方案1】:

首先,如果您正在构建依赖组件,则不需要使用@AndroidEntryPoint,即使在我的情况下,使用@AndroidEntryPoint 的动态功能模块也会导致它无法编译。

编辑:在您的情况下,构建依赖组件或使用 builder 构建组件看起来没有必要。如果是这样,您可以使用下面的答案会有所帮助,如果您不需要依赖组件,我将添加另一个编辑以简单的方式完成。

您应该使用EntryPointAccessors.fromApplication()EntryPointAccessors.fromActivity()EntryPointAccessors.fromFragment() 创建一个接口,该接口具有提供方法@InstallIn@EntryPoint 注释。我解释了 here 如何使用 Hilt 构建依赖组件和动态功能模块,您可以找到 full sample in this git repo

首先使用您提供的依赖项创建一个模块:

@Module
@InstallIn(ApplicationComponent::class)
class CoreModule {

    @Singleton
    @Provides
    fun provideCoreDependency(application: Application) = CoreDependency(application)

    @Provides
    fun provideCoreActivityDependency(context: Application) = CoreActivityDependency(context)
}

您可以根据您的结构将ApplicationComponent 更改为ActivityComponentFragmentComponent

然后使用 @EntryPoint@InstallIn 注释和提供方法构建依赖项接口,这是您向依赖组件提供依赖项的方式。

@EntryPoint
@InstallIn(ApplicationComponent::class)
interface CoreDependencies {

    /*
     * Provision methods to provide dependencies to components that
     * depend on this component
     */
    fun coreDependency(): CoreDependency

    fun coreActivityDependency(): CoreActivityDependency

}

现在构建你应该创建的组件,它是 CardAdapterComponent 给你的

@Component(
        dependencies = [CoreDependencies::class],
        modules = [CameraModule::class]
)
interface CameraComponent {

    fun inject(cameraFragment1: CameraFragment1)
    fun inject(cameraFragment2: CameraFragment2)


    fun inject(cameraActivity: CameraActivity)

    @Component.Factory
    interface Factory {
        fun create(coreDependencies: CoreDependencies, @BindsInstance application: Application): CameraComponent
    }

}

我用的是工厂模式,你可以用builder,都一样。

要将您的依赖组件注入Activity,您需要使用EntryPoints 获取组件。

private fun initHiltDependencyInjection() {

    val coreComponentDependencies = EntryPointAccessors.fromApplication(
            applicationContext,
            CoreDependencies::class.java
    )

    DaggerCameraComponent.factory().create(
            coreComponentDependencies,
            application
    )
            .inject(this)


}

注入到Fragment

private fun initCoreDependentInjection() {

    val coreComponentDependencies = EntryPointAccessors.fromApplication(
            requireActivity().applicationContext,
            CoreDependencies::class.java
    )

    DaggerCameraComponent.factory().create(
            coreComponentDependencies,
            requireActivity().application
    )
            .inject(this)

}

【讨论】:

  • ive 给了你赏金作为唯一认真的答案大声笑会尝试这个并接受它,如果它有帮助,非常感谢
  • 在我提供的链接中,您可以查看 Dagger Hilt 的基础知识。它会帮助你。当您的片段在动态功能模块中或在另一个没有 @AnroidEntryPoint 的对象中时无法访问应用程序组件时,您需要使用依赖组件或构建器可以像 ContentProvider 等。我建议您首先检查 github 链接到看看简单的匕首刀柄注射是如何工作的,我想它对你有用。您也可以查看我的问题以查看结构。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-17
  • 1970-01-01
  • 1970-01-01
  • 2012-09-07
  • 2011-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多