首页 > 解决方案 > Dagger2 - 在具有即时应用和动态模块支持的 Android 应用中注入

问题描述

我正在尝试设置具有即时应用程序和动态模块支持的 Android 应用程序的样板/概念证明库,同时注入一些第三方库,如 Room 和 Retrofit。它是用 Kotlin 编写的。代码可以在GitHub-Stabber中找到。

我正在添加对 SplitCompat API 的支持,以便我可以动态安装动态模块,如App Bundle - Play Core Guide中所述。

在本指南中,描述了可以SplitCompatApplication在他们的 android 清单中用作他们的应用程序实现(这里我假设这部分在基本模块的清单中,由于所有模块的依赖模型,如果我错了,请纠正我) .

我所做的是遵循它描述SplitCompatApplication实际在做什么的部分,据说它只是覆盖Application's ,如此处所述:

SplitCompatApplication简单地覆盖ContextWrapper.attachBaseContext()以包含SplitCompat.install(Context applicationContext). 如果您不希望您的Application类扩展SplitCompatApplication,您可以attachBaseContext()手动覆盖该方法,如下所示:

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    // Emulates installation of future on demand modules using SplitCompat.
    SplitCompat.install(this);
}

所以我确实做到了这一点,但是考虑到我支持即时应用程序的版本,所以我的这个函数覆盖的主体实际上是:

override fun attachBaseContext(base: Context?) {
    super.attachBaseContext(base)
    val isInstant = InstantApps.isInstantApp(this)
    if (!isInstant) {
        SplitCompat.install(this)
    }
}

因此,除了之前链接指南中显示的代码之外,我只是取出检查并将其存储在一个变量中,这仍然会产生相同的结果。我的问题是我不能再运行我的应用程序了,因为它抛出了这个异常:

Process: app.instant.stabber.app, PID: 6788
    java.lang.RuntimeException: Unable to instantiate application app.instant.stabber.android.StabberApplication: java.lang.IllegalStateException: Application context is null!
        at android.app.LoadedApk.makeApplication(LoadedApk.java:1017)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5940)
        at android.app.ActivityThread.-wrap1(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1755)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6753)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:482)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
     Caused by: java.lang.IllegalStateException: Application context is null!
        at com.google.android.instantapps.InstantApps.isInstantApp(InstantApps.java:62)
        at app.instant.stabber.android.StabberApplication.attachBaseContext(StabberApplication.kt:30)
        at android.app.Application.attach(Application.java:218)
        at android.app.Instrumentation.newApplication(Instrumentation.java:1107)
        at android.app.Instrumentation.newApplication(Instrumentation.java:1091)

我什至尝试过这样的事情,以解决上下文(应用程序..?)似乎为空的事实:

 override fun attachBaseContext(base: Context?) {
    super.attachBaseContext(base)
    this?.let { me ->
        val isInstant = InstantApps.isInstantApp(me)
        if (!isInstant) {
            SplitCompat.install(me)
        }
    }
}

我真的不知道从这里去哪里。有人对造成这种情况的原因有任何想法吗?我唯一能想到的就是清单出了点问题,因为这是我之前一直在努力解决的问题。清单以及在这种 Android 应用程序模块化中处理资源的方式非常奇怪(我不得不将一些字符串值放入基础而不是即时功能等)。

编辑:在当前代码中,我没有手动覆盖它以适应即时应用程序(正如我链接的指南所建议的那样),而是我只是将 SplitCompatApplication 子类化。它似乎可以运行,但我尚未测试安装任何动态模块。

编辑2:我最后想出了什么,但我想知道为什么我必须在第一时间这样做,即使我遵循了确切的说明:

override fun attachBaseContext(base: Context?) {
    super.attachBaseContext(base)
    this.applicationContext?.let { _ ->
        val isInstant = InstantApps.isInstantApp(this)
        if (!isInstant) {
            SplitCompat.install(this)
        }
    }
}

标签: androiddagger-2

解决方案


推荐阅读