替换 Android App Bundle (.aab) 文件中 BUNDLE-METADATA 文件夹中的文件

Replace files in BUNDLE-METADATA folder in Android App Bundles (.aab) file

提问人:Nitin Sethi 提问时间:10/19/2023 最后编辑:ΓDΛNitin Sethi 更新时间:10/27/2023 访问量:96

问:

如何替换Android App Bundles文件中BUNDLE-METADATA文件夹中现有目录中的文件?(.aab)

对于本机崩溃的反符号化,我们希望将 中的现有 .dbg 文件替换为从其他源接收的文件。这些现有的 .dbg 是在生成过程中创建的。出于某种原因,使用在构建期间创建的 .dbg 无法帮助在本地和在 Play 开发控制台中进行去符号化。只有当我们上传原始 .so 文件到开发控制台时,去符号化才会正确发生。path="/BUNDLE-METADATA/com.android.tools.build.debugsymbols/arm64-v8a

此 API 似乎仅适用于添加新文件和目录。https://developer.android.com/reference/tools/gradle-api/8.3/null/com/android/build/api/variant/BundleConfig

是否可以使用替换现有文件?AGP 7.3

安卓 android-gradle-plugin android-app-bundle

评论


答:

4赞 VonC 10/23/2023 #1

在你的方案中,你有一个 Android App Bundle (.aab 文件,其中有一个位于目录中的特定文件。.dbgBUNDLE-METADATA/com.android.tools.build.debugsymbols/arm64-v8a

您的目标是将此现有文件替换为来自不同来源的另一个文件,以帮助对本机崩溃进行去符号化,因为当前文件无法达到其目的。.dbg.dbg

+----------------------------+
| Android App Bundle (.aab)  |
| +------------------------+ |
| | BUNDLE-METADATA        | |
| | +--------------------+ | |
| | | debugsymbols       | | |
| | | +---------------+  | | |
| | | | arm64-v8a     |  | | |
| | | | +-----------+ |  | | |
| | | | | new.dbg   | |  | | | <-- Replaced .dbg file
| | | | +-----------+ |  | | |
| | | +---------------+  | | |
| | +--------------------+ | |
| +------------------------+ |
+----------------------------+

我没有看到对此的任何支持。

修改现有 Android App Bundle (AAB) 中的文件确实会影响其签名,从而可能导致其无效。当您创建 AAB 时,它会使用密钥进行签名,以确保其完整性和真实性。对 AAB 的任何后续修改(例如替换文件)都会更改捆绑包的内容,从而更改其签名。

对于使用 Android App Bundle 发布的应用,还有一种名为“代码透明度”的可选代码签名和验证机制。尽管它独立于用于 app bundle 和 APK 的签名方案运行,但它强调了签名作为验证机制的重要性。


我对生成管道具有完全访问权限。因此,如果在对 app bundle 进行签名和打包之前可以使用任何方法,那就是我正在寻找的。

主要是,我希望在应用程序捆绑包的最终打包完成之前替换生成的文件。就在创建文件夹之前。BUNDLE-METADATA

在这种情况下,最佳方法是在 app bundle 的最终打包和签名发生之前替换文件。app bundle 的完整性和签名保持不变。.dbg

生成管道步骤:

+---------------------+      +---------------------+
| Initial Build Steps | ---> | Generate .dbg files |
+---------------------+      +---------------------+
                                     |
                                     V
     +----------------------------------+      +--------------------------+
     | Replace .dbg with external file  | ---> | Final Packaging & Signing|
     +----------------------------------+      +--------------------------+
  • 像往常一样生成应用,直到生成文件为止。.dbg

  • 将生成的文件替换为您拥有的外部文件(脚本或简单的 cp 步骤):.dbg.dbg

    cp path/to/external.dbg path/to/build/intermediates/debugSymbols/arm64-v8a/new.dbg
    

    这可以通过自定义 gradle 任务编写 Gradle 插件来完成

  • 继续对 app bundle 进行最终打包和签名**。然后,文件夹及其内容(包括替换的文件)将作为正常生成过程的一部分进行打包和签名。BUNDLE-METADATA.dbg

./gradlew bundleRelease

这样,您可以确保在 app bundle 的最终打包和签名之前替换文件,从而保持 app bundle 的完整性和签名。.dbg


例如:扩展 Android Gradle 插件 (AGP) 可以包括“在最终打包 app bundle 之前替换文件”步骤。

apply plugin: 'com.android.application'

android {
    ...
}

// Define a custom task to replace the .dbg file
task replaceDbgFile {
    doLast {
        println 'Replacing .dbg file...'
        def command = ['cp', 'path/to/external.dbg', 'path/to/build/intermediates/debugSymbols/arm64-v8a/new.dbg']
        command.execute()
        println '.dbg file replaced successfully.'
    }
}

// Make sure the custom task is executed before the bundleRelease task
gradle.tasks.named('bundleRelease').configure {
    dependsOn replaceDbgFile
}

名为的新任务使用 Groovy 方法运行命令,将生成的文件替换为外部文件。
该行确保在任务之前执行任务,该任务对应用包进行打包和签名。
replaceDbgFileexecute()cp.dbg.dbggradle.tasks.named('bundleRelease').configure { dependsOn replaceDbgFile }replaceDbgFilebundleRelease


OP Nitin Sethi评论中补充道:

我最终用于我的新任务,该任务在任务“”或等效任务之后立即复制正确的文件。dependsOnextractReleaseNativeDebugMetadata

您知道使用 Groovy DSL API 进行复制和删除的更好方法吗?

dependsOn 方法是一种可靠的方法,可确保自定义任务在生成过程中的适当时间点执行,特别是在任务之后。这样,在继续执行生成管道中的后续步骤之前,所需的文件就已就位。
另请参阅 Cédric Champeau 的“A Gradle quickie: properly using dependsOn”。
extractReleaseNativeDebugMetadata

为了在 Gradle 中使用 Groovy DSL 复制和删除文件,有更多惯用的方法可以利用 Gradle 的内置任务类型和方法:

您可以使用 Gradle 的复制任务类型来定义用于复制文件的任务。

task copyDbgFile(type: Copy) {
    from 'path/to/external.dbg'
    into 'path/to/build/intermediates/debugSymbols/arm64-v8a'
    rename { String fileName ->
        'new.dbg'  // Rename if necessary
    }
}

使用 Gradle 的 Delete 任务类型定义用于删除文件的任务。

task deleteOldDbgFile(type: Delete) {
    delete 'path/to/build/intermediates/debugSymbols/arm64-v8a/old.dbg'
}

确保在生成过程中的正确位置执行复制和删除任务。

gradle.tasks.named('extractReleaseNativeDebugMetadata').configure {
    finalizedBy copyDbgFile, deleteOldDbgFile
}

评论

0赞 Nitin Sethi 10/23/2023
我对生成管道具有完全访问权限。因此,如果在对 app bundle 进行签名和打包之前可以使用任何方法,那就是我正在寻找的。主要是,我希望在应用程序捆绑包的最终打包完成之前替换生成的文件。就在创建 BUNDLE-METADATA 文件夹之前。
0赞 VonC 10/23/2023
@NitinSethi 我已经编辑了答案以解决您的评论。
0赞 Nitin Sethi 10/27/2023
感谢您的详细回复。我最终将 dependsOn 用于我的新任务,该任务在任务“extractReleaseNativeDebugMetadata”或等效任务之后立即复制正确的文件。您知道使用 Groovy DSL API 进行复制和删除的更好方法吗?
1赞 VonC 10/27/2023
@NitinSethi 我已经编辑了答案以解决您的评论。