Пакеты приложений для Android: возникла проблема при разборе пакета (только динамический функциональный модуль)

#android #module #android-app-bundle #dynamic-delivery

#Android #модуль #android-app-bundle #динамическая доставка

Вопрос:

Я пытаюсь реализовать пакеты приложений для Android, и мне нужно, чтобы это работало за пределами Play Store.

  • Я создал новый проект с активностью, содержащей кнопку
  • Я создал новый модуль динамических функций через File> New> New Module> Dynamic Feature Module

Теперь структура моего проекта Android выглядит следующим образом: (исключая не значимые файлы)

 app
 ├ AndroidManifest.xml
 ├ java
 │  └ my.package.name
 │    └ MainAtivity
 └ res
    └ layout
       └ activity_main.xml

dynamic_feature
 ├ AndroidManifest.xml
 ├ java
 │  └ my.package.name_dynamic_feature
 │     └ ModuleActivity
 └ res
    └ layout
       └ activity_module.xml
Gradle Scripts
 ├ build.gradle (project)
 ├ bulid.gradle (app)
 └ build.gradle (dynamic_feature)
  

Мой build.gradle (app) файл содержит

 apply plugin: 'com.android.application'
android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "my.package.name"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    dynamicFeatures = [":dynamic_feature"]
    bundle {
        language { enableSplit = true}
        density { enableSplit = true}
        abi { enableSplit = true}
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    api 'com.android.support:appcompat-v7:28.0.0-rc02'
    api 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
  

Мой build.gradle (dynamic_feature) файл содержит

 apply plugin: 'com.android.dynamic-feature'
android {
    compileSdkVersion 28
    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 28
    }
}
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation project(':app')
}
  

и в целях тестирования я запрашиваю свой dynamic_feature с

 Intent intent = new Intent()
    .setClassName(MainActivity.this, "my.package.name_dynamic_feature.ModuleActivity");
startActivity(intent);
  

в OnClickListener прикрепленном к кнопке в моем MainActivity .

Используя сборку > Пакеты сборки / APK (ы) > Пакеты сборки, все строится нормально, я получаю свой app.aab файл и генерирую out.apks файл с помощью bundletool следующей команды

 java -jar bundletool-all-0.9.0.jar build-apks --bundle=D:folderapp.aab --output=D:folderout.apks
  

и после этого я извлекаю их base-master.apk и dynamic_feature-master.apk просто перетаскиваю из out.apks открытых в WinRAR.

Я устанавливаю base-master.apk и работает нормально, за исключением случаев, когда я нажимаю на кнопку, потому что она, очевидно, выдает, java.lang.ClassNotFoundException что она не найдена ModuleActivity .

В то время как при попытке установить мой, dynamic_feature-master.apk я получаю сообщение о том, There was a problem while parsing the package что я не вижу какой-либо заметной ошибки в logcat, когда появляется это сообщение. Я не знаю, как двигаться дальше.

Комментарии:

1. Почему вы извлекаете APK? Не могли бы вы просто запустить «bundletool install-apk» для *.apk, сгенерированных bundletool ранее?

2. @Pierre при этом устройство получит base_master.apk только в первый раз? Я хочу, чтобы моя динамическая функция устанавливалась только по требованию

3. Когда вы используете adb install, он пытается заменить приложение. Поскольку в APK-файле dynamic module отсутствует базовая версия, установка завершается неудачно. Тем не менее, я думаю, что есть флаг, который вы можете передать в adb, чтобы сказать, что это дополнительный APK, а не замена. Я попытаюсь найти его в понедельник. Не стесняйтесь пинговать этот поток снова, если я к тому времени забуду.

Ответ №1:

При использовании adb install без дополнительных флагов он пытается заменить приложение (таким образом, удаляя базовый APK). Поскольку в APK динамического модуля отсутствует базовая версия, установка завершается неудачно.

Чтобы вручную установить APK-файл dynamic module (и его конфигурационные разделы) поверх базового APK, вы можете использовать следующую команду:

 adb install-multiple -r --dont-kill -p com.myapp module-master.apk module-en.apk module-armv7a.apk module-xxxhdpi.apk
  

Вероятно, нам следует добавить удобный метод в bundletool , чтобы сделать то же самое. Если вы чувствуете необходимость в этом, отправьте запрос на функцию в bundletool github project.

Однако обратите внимание, что он не имитирует в точности то, что произойдет при установке модуля через Play Core API, и, в частности, вы не получите INSTALLED обратного вызова.

Лучший способ протестировать установку модулей сегодня — пройти внутренний тестовый трек Play Console.

Надеюсь, это поможет,

Комментарии:

1. Спасибо за ваш ответ @Pierre, когда я запускаю, adb install-multiple... я получаю сообщение adb: не удалось создать исключение сеанса, возникшее при выполнении: java.lang. Исключение IllegalArgumentException: размер должен быть положительным , и я не знаю, к чему это относится.

2. «Вы запускали это после того, как базовая версия уже была установлена?» Да! — Я знаю, что Play Console — лучший способ доставки динамических функций, поскольку Dynamic Delivery специально разработана для работы с Play Store (я полагаю), но для этого проекта необходимо быть автономным от магазина. Я прочитал, что вы инженер Google и являетесь ведущим пользователем android-app-bundle тега здесь, поэтому я уверен, что спрашиваю вас: возможна ли (или будет) динамическая доставка (в конечном итоге с помощью Play Core API) полностью за пределами Play Store?

3. В Google I / O был запущенвнутренний общий доступ к приложениям , который помогает тестировать динамические функции без необходимости создавать трек выпуска, изменять код версии или даже подписывать пакет приложений.

Ответ №2:

нехорошо просто извлекать APK с помощью файла winrar out.apks . Если вы хотите установить только базовый apk, вы можете сделать это с помощью (я предполагаю, что название вашего базового модуля base-master ):

 bundletool install-apks --apks=D:folderout.apks --modules="base-master"
  

--modules Опция дает вам возможность установить только указанные модули. Однако, я думаю, нет способа протестировать динамическую доставку (загрузку динамических модулей по требованию) локально, поскольку ваше приложение взаимодействует с библиотекой Play Core.

Кстати, если вы настаиваете на извлечении APK, вы можете использовать bundle tool:

 bundletool extract-apks 
     --apks=D:folderout.apks
     --output-dir=D:folder2