Koin3.1.6已定义scope仍抛出NoBeanDefFoundException问题排查
问题描述
在特定Fragment内点击推送通知,跳转至应用内另一个Fragment时应用发生崩溃,当前使用Koin版本为3.1.6,捕获到的崩溃信息如下:
Caused by: org.koin.core.error.NoBeanDefFoundException: |- No definition found for class:'br.example.detail.DetailContract$Presenter'. Check your definitions! at org.koin.core.scope.Scope.throwDefinitionNotFound(Scope.kt:304) at org.koin.core.scope.Scope.resolveValue(Scope.kt:274) at org.koin.core.scope.Scope.resolveInstance(Scope.kt:241) at org.koin.core.scope.Scope.get(Scope.kt:204)
现有实现代码
Koin模块定义
scope(named<MainActivity>()) { factory<DetailContract.Presenter> { (view: DetailContract.View) -> DetailPresenter( view = view, monitoring = get(), api = get(), storage = get(), imageProvider = get() ) } }
DetailFragment实现
private val presenter: DetailContract.Presenter by lazy { scope.get { parametersOf(this) } } override val scope: Scope by fragmentScope()
MainActivity实现
private val presenter: MainContract.Presenter by inject { parametersOf(this) } override val scope: Scope by activityScope()
排查修复方案
核心报错原因是作用域不匹配:你把DetailContract.Presenter声明在了named<MainActivity>()的Activity级作用域下,但DetailFragment中使用by fragmentScope()创建了独立的Fragment级作用域,Koin在Fragment自身的作用域链里找不到对应Bean定义,直接抛出异常。之前尝试切换Activity scope不生效,大概率是作用域绑定、初始化时机没处理对,按以下顺序排查:
- 对齐作用域声明和使用逻辑
- 如果Presenter需要跟随Activity生命周期,把Fragment里的scope获取逻辑改成Activity级作用域,不要用
fragmentScope()拿实例,改为通过activityScope()获取依赖,保证查找依赖的作用域和你声明Bean的作用域完全一致。 - 如果Presenter只需要跟随当前DetailFragment生命周期,直接把
DetailContract.Presenter的factory声明从scope(named<MainActivity>())闭包中移出来,要么声明为全局factory,要么定义在对应DetailFragment的scope闭包下,和fragmentScope()匹配。
- 如果Presenter需要跟随Activity生命周期,把Fragment里的scope获取逻辑改成Activity级作用域,不要用
- 校验推送跳转的初始化时机
点击推送触发跳转时,要先确认Koin所有业务模块已经加载完成、MainActivity实例已经完成创建,再执行Fragment事务加载DetailFragment。冷启动场景下不要在Koin初始化完成前、Activity未attach时提前加载Fragment触发依赖注入。 - 校验参数与接口实现
确认DetailFragment已经实现了DetailContract.View接口,调用parametersOf(this)时传入的参数类型和factory声明的入参类型完全匹配,避免类型不匹配导致Koin无法命中对应Bean定义。 - 多模块场景额外校验
如果是组件化多模块工程,确认存放DetailPresenter的Koin模块已经被加载到当前运行的Koin实例中,推送跳转触发跨模块页面时,要提前做好对应业务模块的Koin模块加载,不要出现模块漏加载的问题。
内容的提问来源于stack exchange,提问作者Gustavo Silva
相关产品推荐
相关产品推荐

