我正在尝试设置具有Instant App和Dynamic Module支持的Android应用程序的样板/概念证明存储库,同时注入一些第三方库,例如Room和Retrofit。它是用Kotlin写的。可以在GitHub - Stabber上找到该代码。
我正在增加对SplitCompat API的支持,以便可以动态安装动态模块,如App Bundle - Play Core Guide中所述。
在本指南中,我们描述了可以将SplitCompatApplication
用作其Android清单中的应用程序实现(由于所有模块的依赖关系模型,在此我假设这部分进入了基本模块的清单中,如果我错了请指正)。
我所做的是遵循描述SplitCompatApplication
实际操作的部分,并且据说它只是覆盖Application
,如此处所述:
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);
}
因此,我确实做到了这一点,但是考虑到我支持Instant Apps的版本,因此该函数替代的主体实际上是:
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)
我什至尝试过类似这样的操作来修复Context(应用程序..?)似乎为空的事实:
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
this?.let { me ->
val isInstant = InstantApps.isInstantApp(me)
if (!isInstant) {
SplitCompat.install(me)
}
}
}
尽管如此,我真的不知道该去哪里。是否有人对导致这种情况的原因有任何想法?我唯一能想到的是清单错误,因为这是我以前很努力的工作。清单和在Android应用程序的模块化中处理资源的方式这一事实非常奇怪(我不得不将一些字符串值放在基数而不是即时功能中,等等)。
编辑:在当前代码中,我没有手动覆盖它以适应Instant Apps(如我所链接的指南所建议的),而只是将SplitCompatApplication子类化。它似乎可以运行,但是我尚未测试安装任何动态模块。
编辑2:最后我想出了什么,但我想知道为什么即使我遵循了确切的说明,我也必须在第一地点这样做:
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
this.applicationContext?.let { _ ->
val isInstant = InstantApps.isInstantApp(this)
if (!isInstant) {
SplitCompat.install(this)
}
}
}