迁移您的免安装应用以支持 Android App Bundle

如果您的 Android 免安装应用模块仍在使用已弃用的 Android Gradle 功能插件 (com.android.feature),那么您需要改用基础应用插件 (com.android.application) 和动态功能插件 (com.android.dynamic-feature)。

在 Android Gradle 插件 3.3.0 及更高版本中,基础应用插件包含对免安装体验的支持。也就是说,如果基础应用模块满足提供免安装体验的要求,您就可以自动获得这项优势。然后,您可以使用动态功能插件添加其他功能,这些功能可供用户通过免安装的方式按需下载。通过这种方式,您可以更轻松地在单个项目中同时支持安装式应用体验和免安装应用体验,还可获享使用 Android App Bundle 发布应用的优势。

下表详细说明了您需要迁移到哪些插件:

模块说明 旧插件 新插件
此模块包含用于提供安装式应用体验或免安装应用体验的基础代码、资源和功能。 com.android.feature(包含 baseFeature = true 设置) com.android.application

注意:此模块包含将您的应用构建并打包为 Android App Bundle 或 APK 所需的所有清单和签名信息。

用户可以按需下载的其他模块化功能 com.android.feature com.android.dynamic-feature(模块清单中包含 dist:instant="true"dist:onDemand="false" 设置)
仅在应用的安装式版本中提供的功能的代码和资源。 com.android.application com.android.dynamic-feature(模块清单中包含 dist:instant="false"dist:onDemand="false" 设置)

本页面介绍了如何通过迁移现有免安装应用项目构建支持免安装体验的 Android App Bundle,以及如何构建、测试和发布支持免安装体验的 Android App Bundle。

如果您要为应用创建新的免安装体验,请参阅创建支持免安装体验的功能模块

了解具体变更

当您迁移项目并改用动态功能插件后,Android App Bundle 会为您提供一种全新的方式来构建和发布应用,可以大大简化向用户分发经过优化的 APK 的过程。

app bundle 可以将您应用的所有经过编译的代码和资源打包上传,以此来简化分发过程,但它会将 APK 生成及签名交由 Google Play 来完成。Google Play 的新应用服务模式随后会使用您的 app bundle 针对每位用户的设备配置生成并提供经过优化的 APK,因此用户只需下载运行您的应用所需的代码和资源。您不必再通过构建、签署和管理多个 APK 来支持不同的设备,而用户也可以获得更小且更完善的下载文件包。

使用现已弃用的功能插件时,构建免安装应用需要创建一个基础功能模块,该模块包含所有模块(包括免安装应用模块)的共享代码和资源。其余代码包含在多个非基础功能模块中,这些模块包含免安装体验的入口点。对于应用的安装式版本,您的项目可能包含一个单独的应用模块,该模块仅包含安装式应用所需的代码和 Activity。

当您迁移应用并实现对 Android App Bundle 的支持后,您的应用模块将发挥基础模块的作用,并且您可以将其他安装式体验或免安装体验组织成为功能模块。也就是说,您的项目现在更接近于标准应用项目,具有支持免安装体验的基础模块,并且可以添加其他模块化免安装体验。

如需迁移现有的免安装应用项目并采用更完善的 Android App Bundle 分发模型,请按照下面几部分中所述的步骤操作。

将基础功能模块转换为应用模块

在将基础功能模块转换为主应用模块之前,您需要先按以下方式修改它的 build.gradle 文件:

  1. 删除 baseFeature true 行。
  2. 移除所有使用 featureapplication 依赖项配置的依赖项。

    Groovy

    dependencies {
        ...
        // delete any lines that look like
        // feature project(":foo")
        // feature project(":bar")
        // application project(":app")
    }
    

    Kotlin

    dependencies {
        ...
        // delete any lines that look like
        // feature(project(":foo"))
        // feature(project(":bar"))
        // application(project(":app"))
    }
    
  3. applicationId 以及您希望包含在基础应用模块中的其他任何构建脚本配置从当前的 com.android.application 模块移至 com.android.feature 模块。下面给出了一些示例。对于这一步,或许将先前应用模块的 build.gradle 中的 android 代码块复制粘贴到新应用模块的 build.gradle 文件中会更加简单,这取决于具体的 build.gradle 设置。不过,您在执行此操作时应格外小心。

    Groovy

    android {
        ...
        defaultConfig {
            // You need to move the application ID from the app module
            // to your feature module.
            applicationId "com.example.myapp"
            ...
        }
        // Some additional build configurations you might want to
        // copy from your current ‘app’ module may include ProGuard
        // rules and code shrinking settings.
        buildTypes {
            release {
                minifyEnabled true
                proguardFiles getDefaultProguardFile(
                  'proguard-android-optimize.txt'),
                  'proguard-rules.pro'
            }
        }
    }
    

    Kotlin

    android {
        ...
        defaultConfig {
            // You need to move the application ID from the app module
            // to your feature module.
            applicationId = "com.example.myapp"
            ...
        }
        // Some additional build configurations you might want to
        // copy from your current ‘app’ module may include ProGuard
        // rules and code shrinking settings.
        buildTypes {
            getByName("release") {
                minifyEnabled = true
                proguardFiles(
                    getDefaultProguardFile("proguard-android-optimize.txt"),
                    "proguard-rules.pro"
                )
            }
        }
    }
    
  4. 在清单中添加相应的软件包分发标记,将功能模块标记为支持免安装体验的模块,如下所示。

    <manifest ... xmlns:dist="http://schemas.android.com/apk/distribution">
        <dist:module dist:instant="true" />
        ...
    </manifest>
    
  5. 将功能模块的插件类型更改为 com.android.application,以将其转换为基础应用模块:

    Groovy

    // Replace  "plugins { id 'com.android.feature' }"
    // with the following
    plugins {
      id 'com.android.application'
    }
    

    Kotlin

    // Replace  "plugins { id("com.android.feature") }"
    // with the following
    plugins {
        id("com.android.application")
    }
    

将旧应用模块转换为安装时功能模块

如果旧应用模块中没有代码或资源,您可以直接将其删除,因为您在上一部分中执行的步骤已将您的功能模块转换为应用的基础应用模块。

但是,如果旧应用模块中有代码和资源,并且它们代表您希望用户在安装应用时可获得的功能,请按照本部分中的步骤将应用模块转换为功能模块。

创建功能模块需要将插件类型从 com.android.application 更改为 com.android.dynamic-feature,还需要在 build.gradle 中进行一些其他更改,如下所示:

  1. 将插件类型从 com.android.application 更改为 com.android.dynamic-feature

    Groovy

    // Replace "plugins { id 'com.android.feature' }"
    // with the following:
    plugins {
      id 'com.android.dynamic-feature'
    }
    

    Kotlin

    // Replace "plugins { id("com.android.application") }"
    // with the following:
    plugins {
        id("com.android.dynamic-feature")
    }
    
  2. 如上一部分中所述,确保您已将 com.android.application 插件所需的构建配置(如 applicationIdproguardFiles 规则)移至基础应用模块。

  3. 将模块重命名为“installed_feature”之类的名称,具体操作步骤如下:

    1. 从菜单栏中依次选择 View > Tool Windows > Project,打开 Project 窗格。
    2. 右键点击功能模块,然后依次选择 Refactor > Rename
    3. 在出现的对话框中,选择 Rename module,然后点击 OK
    4. 输入模块的新名称,然后点击 OK
  4. 与第 3 步类似,将您在上一部分中创建的新应用模块重命名为“app”之类的名称。

  5. 在功能模块的 build.gradle 文件中将“app”模块添加为实现依赖项,如下所示。

    Groovy

    dependencies {
        ...
        // In the feature module, add an implementation dependency
        // on the base app module.
        implementation project(":app")
    }
    

    Kotlin

    dependencies {
        ...
        // In the feature module, add an implementation dependency
        // on the base app module.
        implementation(project(":app"))
    }
    
  6. 将功能添加到新应用模块的 build.gradle 文件中。

    Groovy

    android {
        ...
        // In the base app module, specify each feature module.
        dynamicFeatures = [":installed_feature"]
    }
    

    Kotlin

    android {
        ...
        // In the base app module, specify each feature module.
        dynamicFeatures.addAll(listOf(":installed_feature"))
    }
    
  7. 在功能模块的清单中添加相应的软件包分发标记,将功能模块标记为可安装的模块。

    <manifest ... xmlns:dist="http://schemas.android.com/apk/distribution">
        <dist:module dist:instant="false" dist:onDemand="false"
                dist:title="@string/title_dynamic_feature">
            <dist:fusing dist:include="true" />
        </dist:module>
        ...
    </manifest>
    

将其他功能模块转换为支持免安装体验的功能模块

如果您已将应用的其他功能模块化处理为多个功能模块,则需要按照本部分中的步骤将这些模块转换为支持免安装体验的功能模块。

对于项目中剩余的每个功能模块,请按以下步骤将它们转换为支持免安装体验的功能:

  1. build.gradle 文件中的插件类型更改为 com.android.dynamic-feature,如下所示:

    Groovy

    // Replace 'com.android.feature' with 'com.android.dynamic-feature'
    plugins {
      id 'com.android.dynamic-feature'
    }
    

    Kotlin

    // Replace "com.android.feature" with "com.android.dynamic-feature"
    plugins {
        id("com.android.dynamic-feature")
    }
    
  2. 在清单中添加以下内容,将每个功能模块标记为支持免安装体验的模块。

    <manifest ... xmlns:dist="http://schemas.android.com/apk/distribution">
        <dist:module dist:instant="true" dist:onDemand="false"
                dist:title="@string/title_dynamic_feature">
            <dist:fusing dist:include="true" />
        </dist:module>
        ...
    </manifest>
    
  3. 将功能模块添加到新应用模块的 build.gradle 文件中,您之前已在该文件中将 installed_feature 添加到功能模块列表中。

    Groovy

    android {
       ...
       dynamicFeatures = [":installed_feature", ":feature_1", ":feature_2"]
       // or whichever name exists for the instant enabled feature module
    }
    

    Kotlin

    android {
       ...
       dynamicFeatures.addAll(listOf(":installed_feature", ":feature_1", ":feature_2"))
       // or whichever name exists for the instant enabled feature module
    }
    

构建、测试和发布新的支持免安装体验的 app bundle

完成本页面所述步骤后,您的项目就可以生成单个工件(即 Android App Bundle)。您可以使用此工件将应用的安装式版本和免安装版本发布到 Google Play 管理中心,并且可以分别针对免安装应用轨道和安装式应用轨道单独进行发布。此外,借助 app bundle,您还可以获得一项优势,那就是针对每位用户的设备配置提供经过优化的 APK,因此他们只需下载运行您的应用所需的代码和资源。也就是说,您不必再通过构建、签署和管理多个 APK 来支持不同的设备,而用户也可以获得更小且更完善的下载文件包。

如需开始构建和测试支持免安装体验的 app bundle,请转到构建 app bundle