【问题标题】:Using dagger-injected objects in attachBaseContext在 attachBaseContext 中使用 dagger-injected 对象
【发布时间】:2018-11-15 22:23:48
【问题描述】:

我需要在我的活动的attachBaseContext 中访问我的SharedPreferences 实例(这样我就可以在那里设置语言环境),但是注入的SharedPreferences 实例在那里不可用,因为注入发生在@987654325 @ 方法,在 attachBaseContext 调用之后运行。我正在使用 dagger2 进行依赖注入。

知道如何避免创建新的SharedPreferences 实例吗?

编辑:

好的,所以我认为问题是我尝试使用匕首太多,我认为在这种情况下它根本不适合。在每个活动的attachBaseContext 中,我必须更新语言环境,我将这个更新逻辑提取到LocaleManager,它需要访问SharedPreferences 实例和Context,我在attachBaseContext 中获得了ContextSharedPreferences 实例已经在 AppModule 中,但我仍然无法将 @Inject 它添加到 attachBaseContext 调用之前的活动中,因为活动的注入发生在 attachBaseContext 之后。

【问题讨论】:

  • 你为什么不尝试在类扩展应用程序中启动 dagger2 组件?比在活动中?
  • 是的,我想不出任何其他解决方案,我会尝试,谢谢!
  • 嗨,你能帮我的朋友解决同样的问题吗,请检查一下链接stackoverflow.com/q/53277662/3946958
  • 我最终手动创建了 SharedPreferences 实例,没有匕首 @LeoDroidcoder
  • 是的,这里也一样。似乎这是唯一的方法

标签: android dagger-2


【解决方案1】:

只要您可以访问您的Component,您就可以添加provision method

@Singleton
@Component(modules = [AppModule::class])
interface AppComponent {

    fun inject(myActivity: MyActivity)

    fun sharedPreferences(): SharedPreferences

    ...
}

然后直接通过Component 访问您的SharedPreferences

class MyActivity : AppCompatActivity() {

    override fun attachBaseContext(newBase: Context) {
        val sharedPreferences = component.sharedPreferences()
        ...
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        component.inject(this)
    }

}

【讨论】:

  • 感谢您的回答!我正在使用@ContributesAndroidInjector 实现,这样我就不会创建任何组件。 ApplicationComponent 是我唯一拥有的,因此这将导致将 SharedPreferences 移动到应用程序级别,但我将研究该解决方案
  • 在这种情况下,对AndroidInjection.inject(this) 的调用会创建一个组件,即(生成的)MyActivitySubcomponent。因此,限定SharedPreferences 的活动不会帮助您“避免新实例”。上面的答案,即使提到了dagger.android 包,也应该是一个选项。除了重构你的逻辑。
  • 您好,您能帮我的朋友解决同样的问题吗?请检查一下链接stackoverflow.com/q/53277662/3946958
  • 不会工作,因为必须先调用 onCreate 注入,但在 onCreate 之前调用 attachBaseContext,这样你就会有 NullPointer
【解决方案2】:

你可以这样注入:

    @EntryPoint
    @InstallIn(SingletonComponent::class)
    interface PreferencesProvider {
    
        fun getPreferences(): Preferences
    }
    
    abstract class BaseActivity ... {
        private lateinit var preferences: Preferences

        override fun attachBaseContext(newBase: Context) {
           initPreferences(newBase)
           super.attachBaseContext(ContextLocaleWrapper.wrap(newBase,preferences.getLanguage()))
        }

        private fun initPreferences(context: Context) {
            preferences = EntryPointAccessors.fromApplication(
                context.applicationContext,
                PreferencesProvider::class.java
            ).getPreferences()
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-10
    • 1970-01-01
    相关资源
    最近更新 更多