Я пытаюсь настроить шаблонный / проверочный концепт-репозиторий для приложения Android с поддержкой Instant App и Dynamic Module, в то же время внедряя некоторые сторонние библиотеки, такие как Room и Retrofit. Это написано на Kotlin. Код можно найти на GitHub - Stabber .
Я нахожусь на этапе добавления поддержки API SplitCompat, чтобы я мог динамически устанавливать динамические модули, как описано в App Bundle - Руководство по игре на ядре .
В этом руководстве описано, что можно использовать 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 очень странный (некоторые строковые значения, которые мне пришлось поместить в базу вместо мгновенных функций и т. Д.).
РЕДАКТИРОВАТЬ: В текущем коде я не переопределяю его вручную, чтобы приспособить Мгновенные приложения (как предложено в руководстве, которое я связал), и вместо этого я просто подкласс SplitCompatApplication. Кажется, он работает, но я еще не тестировал установку динамических модулей.
РЕДАКТИРОВАТЬ 2: То, что я придумал в конце, но я хочу знать, почему я должен сделать это на первом месте, хотя я следовал точным инструкциям:
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
this.applicationContext?.let { _ ->
val isInstant = InstantApps.isInstantApp(this)
if (!isInstant) {
SplitCompat.install(this)
}
}
}