android - 通过构建器注入(inject)的 Hilt 适配器为空

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

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

@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 但我不能在组件中放置提供方法,我查看了 Dagger 迁移指南 here这对我来说有点复杂,因为在切换到刀柄之前我只有几个星期用 Dagger ,但指南提到

Finally, you may have to redesign some things if they were configured differently for different activity or fragment components. For example, you could use a new interface on the activity to provide the object.


所以我尝试了这个,这让我实现了接口(interface),然后返回了一个卡适配器,但我不确定我应该在这里返回什么,欢迎任何帮助
这是我的卡适配器组件
@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<>();
}

最佳答案

首先你不需要使用@AndroidEntryPoint如果您正在构建您的 依赖组件 , 即使在我的情况下使用 @AndroidEntryPoint 的动态功能模块导致它无法编译。
编辑:在您的情况下,构建依赖组件或使用 builder 构建组件看起来没有必要。如果是这样,您可以使用下面的答案会有所帮助,如果您不需要依赖组件,我将添加另一个编辑以简单的方式完成。
您应该使用 EntryPointAccessors.fromApplication() , EntryPointAccessors.fromActivity()EntryPointAccessors.fromFragment()创建一个具有 的接口(interface)提供方法@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)
}
您可以更改ApplicationComponentActivityComponentFragmentComponent取决于你的结构。
然后用@EntryPoint构建一个依赖接口(interface)和 @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,两者都是一样的。
将您的依赖组件注入(inject) Activity您需要使用 EntryPoints 获取组件.
private fun initHiltDependencyInjection() {

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

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


}
注入(inject)Fragment :
private fun initCoreDependentInjection() {

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

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

}

关于android - 通过构建器注入(inject)的 Hilt 适配器为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62728741/

相关文章:

android - 如何将 Timber 日志重定向到 Junit logcat

android - 如何将 ImageView 半重叠放置在 Fragment 中的 ConstraintLayout 顶部边界上?

java - 在多个 fragment/Activity 之间通信大对象。接口(interface)/EventBus 最佳实践

angularjs - ngInject 和闭包编译器

c# - Unity - 如何对同一类型使用多个映射并注入(inject)到一个对象中

android - 自定义标题栏定位

android - 如何使用加速度传感器检测设备主体上的敲击

android - 编辑文本显示异常 Invalid Int ""

Android DialogFragment No_Title 特性影响布局

java - Spring:未收到电子邮件消息