Android App Bundles: there was a problem while parsing the package (dynamic feature module only)

3.2k Views Asked by At

I am trying to implement Android App Bundles and I need it to work outside of the Play store.

  • I have created a new project with an activity containing a button
  • I have created a new Dynamic Feature Module through File > New > New Module > Dynamic Feature Module

Now my Android project structure is as follows: (omitting not meaningful files)

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)

My build.gradle (app) file contains

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'
}

My build.gradle (dynamic_feature) file contains

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

and for testing purposes I request my dynamic_feature with

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

in an OnClickListener attached to the button in my MainActivity.

Using Build > Build Bundle(s)/APK(s) > Build Bundle(s) everything builds fine, I get my app.aab file and I generate the out.apks file using bundletool with the following command

java -jar bundletool-all-0.9.0.jar build-apks --bundle=D:\folder\app.aab --output=D:\folder\out.apks

and after that, I extract base-master.apk and dynamic_feature-master.apk simply dragging them out of out.apks opened in WinRar.

I install base-master.apk and works fine except for when I click on the button because it obviously throws java.lang.ClassNotFoundException for not finding ModuleActivity.

While when I try to install my dynamic_feature-master.apk I get a message saying There was a problem while parsing the package and I don't see any noticeable error in the logcat when this message comes out. I don't know how to go forward.

2

There are 2 best solutions below

0
On BEST ANSWER

It's not okay to simply extract the apks using winrar out.apks file. If you want to install only the base apk, you can do it by (I assume the name of your base module is base-master):

bundletool install-apks --apks=D:\folder\out.apks --modules="base-master"

The --modules option gives you the chance to install just the specified modules. However, I guess there is no way to test the dynamic delivery (on-demand download of dynamic modules) locally since your app interacts with Play Core library.

By the way, if you are insisted on extracting the APKs, you can use bundle tool:

bundletool extract-apks 
     --apks=D:\folder\out.apks
     --output-dir=D:\folder2
3
On

When you use adb install without additional flags, it tries to replace the app (thus removing the base APK). Because the dynamic module APK is missing the base, it fails installing.

To manually install a dynamic module APK (and its config splits) on top of the base APK, you can use the following command:

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

We should probably add a convenience method in bundletool to do the same. If you feel the need for this, then file a feature request on bundletool github project.

Note however that it doesn't simulate exactly what would happen when you install the module via the Play Core API, and in particular you will not get the INSTALLED callback.

The best way to test installation of modules today is to go through the internal test track of the Play Console.

Hope that helps,