androidmoduleandroid-app-bundledynamic-delivery

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


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

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.


Solution

  • 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