如何使用Hilt对两个自定义类实现字段注入?解决初始化报错
解决Dagger-Hilt注入LocationsListAdapter的依赖问题
问题核心:LocationsListAdapter是你手动实例化的类,并非Hilt管理的组件(如Activity/Fragment),因此Hilt不会自动处理它的字段注入,导致lateinit property categoryAvatar not initialized报错。以下是两种可行解决方案:
方案一:构造函数注入(推荐)
直接将CategoryAvatar作为适配器的构造参数,从Hilt管理的组件(如Activity/Fragment)中传入实例,这是最符合依赖注入设计原则的方式。
修改LocationsListAdapter.kt
class LocationsListAdapter( private val locationList: List<Result?>, private val categoryAvatar: CategoryAvatar // 新增构造参数 ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { private val VIEW_TYPE_ITEM: Int = 0 private val VIEW_TYPE_LOADING: Int = 1 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { // 直接使用categoryAvatar即可,无需lateinit字段 if (viewType == VIEW_TYPE_ITEM){ val view = LayoutInflater.from(parent.context).inflate(R.layout.locations_list_item , parent , false) return ItemViewHolder(view) } else { val view = LayoutInflater.from(parent.context).inflate(R.layout.item_loading , parent , false) return LoadingViewHolder(view) } } // 其他方法中直接调用categoryAvatar.getImageResourceId()即可 }
在创建适配器的组件中注入依赖
比如在Activity中:
@AndroidEntryPoint class LocationListActivity : AppCompatActivity() { @Inject lateinit var categoryAvatar: CategoryAvatar override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_location_list) // 初始化数据源 val locationList: List<Result?> = fetchLocations() // 创建适配器并传入依赖 val adapter = LocationsListAdapter(locationList, categoryAvatar) binding.recyclerView.adapter = adapter } }
方案二:使用EntryPoint注入(适配不想修改构造函数的场景)
通过EntryPoint从应用上下文获取Hilt管理的依赖,无需修改适配器构造函数。
1. 创建EntryPoint接口
@EntryPoint @InstallIn(SingletonComponent::class) interface CategoryAvatarEntryPoint { fun getCategoryAvatar(): CategoryAvatar }
2. 在适配器中初始化依赖
class LocationsListAdapter( private val locationList: List<Result?> ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { private lateinit var categoryAvatar: CategoryAvatar private val VIEW_TYPE_ITEM: Int = 0 private val VIEW_TYPE_LOADING: Int = 1 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { // 仅在首次初始化时获取依赖 if (!::categoryAvatar.isInitialized) { val entryPoint = EntryPointAccessors.fromApplication( parent.context.applicationContext, CategoryAvatarEntryPoint::class.java ) categoryAvatar = entryPoint.getCategoryAvatar() } if (viewType == VIEW_TYPE_ITEM){ val view = LayoutInflater.from(parent.context).inflate(R.layout.locations_list_item , parent , false) return ItemViewHolder(view) } else { val view = LayoutInflater.from(parent.context).inflate(R.layout.item_loading , parent , false) return LoadingViewHolder(view) } } }
注意事项
- 确保你的Application类已添加
@HiltAndroidApp注解,这是Hilt初始化的基础。 - 使用方案一时,创建适配器的组件(Activity/Fragment)必须添加
@AndroidEntryPoint注解,否则Hilt无法注入CategoryAvatar。
内容的提问来源于stack exchange,提问作者Amin soley
相关产品推荐
相关产品推荐

