3

我正在尝试实现 Android App Bundles,我需要它在 Play 商店之外工作。

  • 我创建了一个包含按钮的活动的新项目
  • 我通过File > New > New Module > Dynamic Feature 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

使用Build > Build Bundle(s)/APK(s) > Build Bundle(s)一切都很好,我得到我app.aab的文件并out.apks使用bundletool以下命令生成文件

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

之后,我提取base-master.apkdynamic_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 中没有看到任何明显的错误。我不知道如何前进。

4

2 回答 2

3

当您在adb install没有附加标志的情况下使用时,它会尝试替换应用程序(从而删除基本 APK)。因为动态模块 APK 缺少基础,所以安装失败。

要在基础 APK 之上手动安装动态模块 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 项目上提交功能请求。

但是请注意,当您通过 Play Core API 安装模块时,它并不能准确模拟会发生什么,特别是您不会收到INSTALLED回调。

今天测试模块安装的最佳方法是通过 Play 管理中心的内部测试轨道。

希望有帮助,

于 2019-04-07T17:23:54.423 回答
0

不能简单地使用 winrarout.apks文件提取 apk。如果您只想安装基础 apk,您可以通过(我假设您的基础模块的名称是base-master)来完成:

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

--modules选项使您有机会仅安装指定的模块。但是,我想没有办法在本地测试动态交付(动态模块的按需下载),因为您的应用程序与Play Core library交互。

顺便说一句,如果您坚持要提取 APK,可以使用捆绑工具

bundletool extract-apks 
     --apks=D:\folder\out.apks
     --output-dir=D:\folder2
于 2019-04-05T18:26:39.320 回答