首页
/ Kodein-DI 中 Android 系统服务的依赖注入问题解析

Kodein-DI 中 Android 系统服务的依赖注入问题解析

2025-06-25 12:59:05作者:蔡丛锟

问题背景

在使用 Kodein-DI 框架进行 Android 开发时,从版本 5 迁移到版本 7 后,开发者可能会遇到一个常见问题:当尝试获取 Android 系统服务(如 SharedPreferences 或 ConnectivityManager)时,会抛出 DI$NotFoundException 异常,尽管容器中确实存在这些类型的绑定。

问题分析

在 Kodein-DI 7.x 版本中,Android 相关的系统服务绑定方式发生了变化。通过查看容器日志可以发现,所有 Android 系统服务都被标记为 contexted,这意味着这些绑定需要一个 Android Context 上下文才能正确解析。

解决方案

要正确获取这些系统服务,需要在注入时明确指定上下文。以下是正确的使用方式:

val myModule = DI.Module {
    bindSingleton<AppSettingsService> {
        AppSettingsServiceImpl(
            context = instance(),
            preferences = on(instance<Context>()).instance(arg = "name")
        )
    }
}

关键点在于 on(instance<Context>()) 这部分代码,它明确指定了 SharedPreferences 的获取需要基于特定的 Context 实例。

技术原理

Kodein-DI 7.x 对 Android 系统服务的绑定做了更严格的上下文管理:

  1. 所有 Android 系统服务现在都是 contexted 绑定
  2. 这意味着它们必须在一个特定的 Context 上下文中解析
  3. 直接使用 instance() 无法满足这种上下文要求
  4. 必须使用 on(context).instance() 的形式明确指定上下文

最佳实践

  1. 对于 Android 系统服务,总是使用 on(context).instance() 形式获取
  2. 确保在模块绑定时已经正确导入了 androidXModule
  3. 检查 Context 实例是否正确可用
  4. 对于需要名称参数的绑定(如 SharedPreferences),确保正确传递参数

总结

Kodein-DI 7.x 版本对 Android 系统服务的绑定方式进行了改进,要求更明确的上下文管理。这种改变虽然增加了少量代码复杂度,但带来了更好的类型安全和上下文管理能力。开发者需要适应这种新的绑定方式,特别是在从旧版本迁移时要注意这一变化。

登录后查看全文
热门项目推荐
相关项目推荐