首页 > 解决方案 > AlertDialog 上下文依赖注入问题

问题描述

我的应用程序是用 Kotlin 编写的,我正在使用 Koin 进行注入。

我有一个用于显示对话框的类,并且需要传入上下文。

该文件如下所示:

class SettingsDialogHelper(val resources: Resources, val context: Context) {
    private var settingsAboutDialog: AlertDialog? = null
    private var settingsPrivacyPolicyDialog: AlertDialog? = null

    fun showSettingsAboutDialog() {
        settingsAboutDialog = AlertDialog.Builder(context, R.style.Theme_MaterialComponents_Light_Dialog)
            .setTitle(resources.getString(R.string.about_dialog_title, resources.getString(R.string.app_name)))
            .setMessage(
                resources.getString(
                    R.string.about_dialog_message,
                    resources.getString(R.string.app_name),
                    resources.getString(R.string.company_name))
            )
            .setPositiveButton(R.string.ok, null)
            .show()
    }

    fun isSettingsAboutDialogVisible(): Boolean = settingsAboutDialog?.isShowing == true
}

我的模块文件如下所示:

val appModule = module {

    single<Resources> { androidContext().resources }

    single { SettingsDialogHelper(get(), androidContext()) }
}

最后,在 MainActivity 我注入这样的:

private val settingsDialogHelper: SettingsDialogHelper by inject()

当我的代码调用显示对话框时,会发生以下崩溃:

I: |    +-- 'android.content.res.Resources'
I: |    +-- 'android.content.Context'
I: \-- (*) Created
D: Shutting down VM

    android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
        at android.view.ViewRootImpl.setView(ViewRootImpl.java:1041)
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:397)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:108)
        at android.app.Dialog.show(Dialog.java:340)
        at androidx.appcompat.app.AlertDialog$Builder.show(AlertDialog.java:1008)
        at com.myapp.apps.blog.main.ui.SettingsDialogHelper.showSettingsAboutDialog(SettingsDialogHelper.kt:23)
        at com.myapp.apps.blog.main.ui.MainActivity.onOptionsItemSelected(MainActivity.kt:44)

我认为这个问题与 AlertDialog.Builder 通常需要一个活动而不是上下文的事实有关,我不想住在我的片段中,但不太明白如何解决这个问题。

任何帮助深表感谢

标签: androiddependency-injectionandroid-alertdialogkoin

解决方案


你需要的是用 koin 注入参数。

在 koin 模块中,您的定义应如下所示:

single { activityContext -> SettingsDialogHelper(get(), activityContext }

然后在注入类中,在运行时传递参数。在您的情况下,在 MainActivity 您可以注入:

private val settingsDialogHelper: SettingsDialogHelper by inject { parametersOf(this) }

您可以在koin 文档中找到更多详细信息


推荐阅读