4

我是匕首和刀柄的新手,我正在尝试使用 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 但我不能在组件中放置提供方法,我在这里查看了匕首迁移指南,这对我来说有点复杂,因为我只有几个星期在切换到刀柄之前用匕首,但指南提到

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

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

这是我的卡适配器组件

@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<>();
}
4

1 回答 1

1

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

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

您应该使用或创建一个接口,该接口具有EntryPointAccessors.fromApplication()带有和注释的配置方法。在这里解释了如何使用 Hilt 构建依赖组件和动态功能模块,你可以在这个 git repo 中找到完整的示例EntryPointAccessors.fromActivity()EntryPointAccessors.fromFragment()@InstallIn@EntryPoint

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

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

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

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

您可以更改ApplicationComponentActivityComponentFragmentComponent取决于您的结构。

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

}
于 2020-07-23T10:27:43.257 回答