Kotlin中通过Dagger向Adapter传参遇ManageScrip注入错误求助
看起来你遇到的核心问题是Dagger找不到ManageScrip实例的提供方式,错误提示已经说得很清楚了:ManageScrip cannot be provided without an @Inject constructor or from an @Provides-annotated method。下面我来一步步帮你解决这个问题:
为什么之前传ArrayList没问题?
你之前在provideAddScriptOrContractAdapter方法里直接new ArrayList<AddScrip>(),相当于手动创建了这个集合实例,不需要Dagger提供依赖。但现在你把ManageScrip作为参数传入Adapter的构造,Dagger需要明确知道这个对象从哪来,所以就报错了。
两种解决方案
方案一:给ManageScrip数据类添加@Inject构造函数
如果你的ManageScrip可以通过无参构造或者Dagger能提供其构造参数的话,直接给它加上@Inject注解:
data class ManageScrip( // 你的字段,比如val id: Int, val name: String等 ) @Inject constructor()
如果ManageScrip的构造有参数,那这些参数也必须能被Dagger提供(要么参数类有@Inject构造,要么在Module里用@Provides提供)。
方案二:在Module中添加@Provides方法提供ManageScrip实例
如果ManageScrip的实例需要从外部获取(比如从Fragment的arguments、API响应或者ViewModel里拿到),那就在AddScriptOrContractFragmentModule里添加一个专门的@Provides方法:
@Module class AddScriptOrContractFragmentModule { // 先提供ManageScrip实例 @Provides fun provideManageScrip(): ManageScrip { // 这里返回你的ManageScrip实例,举几个例子: // 1. 如果是固定测试数据:return ManageScrip(1, "Test Scrip") // 2. 如果从ViewModel获取:可以注入ViewModel后取数据,前提是ViewModel已经被Dagger提供 return ManageScrip(/* 你的初始化逻辑 */) } // 原有的Adapter提供方法 @Provides fun provideAddScriptOrContractAdapter( context: Context, addScriptOrContractViewModel: AddScriptOrContractViewModel, manageScrip: ManageScrip ): AddScriptOrContractAdapter { return AddScriptOrContractAdapter( ArrayList<AddScrip>(), context, manageScrip, addScriptOrContractViewModel ) } }
补充:如果ManageScrip是从Fragment传入的
如果你的manageScrip是在Fragment里初始化的(比如从arguments获取),可以通过Module的构造参数传递这个实例:
// 修改Module,接收manageScrip作为构造参数 @Module class AddScriptOrContractFragmentModule(private val manageScrip: ManageScrip) { @Provides fun provideManageScrip(): ManageScrip { return manageScrip } // 其他@Provides方法不变 }
然后在Fragment里注入时传递这个实例:
class AddScriptOrContractFragment : Fragment() { private lateinit var manageScrip: ManageScrip override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 从arguments获取manageScrip实例(假设你之前用putParcelable存的) manageScrip = requireArguments().getParcelable("manage_scrip")!! // 自定义注入逻辑,传入Module实例 AndroidInjection.inject(this, object : AndroidInjector.Factory<AddScriptOrContractFragment> { override fun create(instance: AddScriptOrContractFragment): AndroidInjector<AddScriptOrContractFragment> { return DaggerAddScriptOrContractFragmentProvider_AddScriptOrContractFragmentFactory.builder() .addScriptOrContractFragmentModule(AddScriptOrContractFragmentModule(instance.manageScrip)) .build() } }) } }
统一Adapter的创建方式
注意看你的Fragment代码:你一边在Module里配置Dagger提供Adapter,另一边又手动new AddScriptOrContractAdapter(...),这会导致依赖注入的逻辑混乱。建议二选一:
- 全手动创建:直接在Fragment里new Adapter,传所有参数,不需要在Module里写
provideAddScriptOrContractAdapter方法。 - 全Dagger注入:在Fragment里用
@Inject lateinit var mAddScriptAdapter: AddScriptOrContractAdapter,让Dagger自动创建Adapter,然后直接设置给RecyclerView。
这样就能避免不必要的依赖冲突啦!
内容的提问来源于stack exchange,提问作者Rupesh

