排除发布构建类型的资产

Exclude assets for release build type

我正在使用 gradle 构建的应用程序中导入一个 android 库,就像这样:

dependencies {
    compile 'com.example:great-lib:0.1-SNAPSHOT'
}

此库仅包含资产、js、css 和要在 webview 中使用的图像,布局如下:

assets/
|-> great.css
|-> great.min.js
|-> great.min.js.map
|-> js/
|   |-> plop.js
|   |-> foo.js
|   ...
|-> img/
|   ...

js 文件夹包含源文件(与源映射一起使用)。我想包括它和用于调试版本的 .map 文件,并且在发布版本中只有缩小的 js,但我找不到这样做的方法。

到目前为止我已经尝试过:

android {
    // this doesn't exclude anything
    packageOptions {
        exclude 'assets/js'
    }
    buildTypes {
        release {
            // this does exclude the js folder, but in both release and debug
            aaptOptions {
                ignoreAssetsPattern "!js"
            }
        }
    }
}

知道我想要的东西是否有可能实现吗?如果可以,如何实现?

(我也考虑过发布两个版本的库(great-libgreat-lib-debug),并且在 debugCompilereleaseCompile 中有依赖关系,但是我宁愿避免这种情况并发布一个版本)

我最后做了以下事情:

android.applicationVariants.all { variant ->

  if (variant.name.contains('Release')) {
    // exclude source and sourcemap from release builds
    def noJsSourceTask = task("delete${variant.name}JsSource", type: Delete) {
      delete "${buildDir}/intermediates/assets/${variant.dirName}/js"
      delete "${buildDir}/intermediates/assets/${variant.dirName}/great.min.js.map"
    }
    variant.mergeAssets.finalizedBy noCeJsSourceTask
  }
}

它工作正常,但有一些我不太喜欢的地方:

  • 我正在处理任务完成后生成的文件(finalizedBy),因此它不能很好地用于 "up-to-date" 检查。但这仅适用于发布版本,我更经常进行调试
  • 要删除的文件的路径是手动构建的。我不确定它是否足够通用,可以按原样在其他项目中重复使用
  • 我正在根据名称选择变体。我会喜欢更有条理的东西。

我想你可以使用proguard。 Proguard 包含在 android studio 中,混淆代码,并删除未使用的 类,如果你想删除应用程序未使用的所有资源。只把你的 build.gradle 这个:

 release {

            minifyEnabled true //remove classes, obfuscate code and zipalign
            shrinkResources true //remove resources
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//autogenerated files
        }

这是 link 相关信息:

您可以个性化、排除特定文件或忽略特定文件

无法通过过滤器。

虽然您可以有 2 个资产文件夹。一个主要的 (src/main/assets) 用于 debugrelease,一个 (src/debug/assets) 仅用于调试版本。

source

Gradle 提供 "aaptOptions, ignoreAssetsPattern" 到 filter/exclude 发布或调试版本的资产文件夹和文件。

调试版本示例(js 文件夹和 great.css 文件):

debug {            
        aaptOptions {
            ignoreAssetsPattern '!js:!great.css:'
        }
    }

发布版本示例(js 文件夹和 great.css 文件):

release {
        aaptOptions {
            ignoreAssetsPattern '!js:!great.css:'
        }
    }

我使用这种方法取得了成功(更新于 2019-5-13 以获得 TaskProvider 支持;查看旧版本的编辑历史记录):

android {
⋮
    applicationVariants.all { variant ->
        if (variant.buildType.name == 'release') {
            variant.mergeAssetsProvider.configure {
                doLast {
                    delete(fileTree(dir: outputDir, includes: ['**/js', '**/*.js.map']))
                }
            }
        }
    }
⋮
}

这应该可以解决@Xavier 回答的问题:

  • 删除是作为变体 mergeAssets 任务的一部分完成的,因此删除反映在任务的输出中,最新检查应该不受影响。
  • 路径是在没有魔法字符串的情况下计算出来的。您可能需要调整包含模式,以防我的示例过于宽松。
  • 变体由 buildType 名称选择,这比匹配整个变体名称(尽管它仍然是字符串类型)问题更少。

请注意,此方法也适用于 res 文件而不是 assets:只需将 mergeAssets 替换为 mergeResources

其他提到 packagingOptionsaaptOptions 的答案树错了,因为它们的范围是 all 变体(它们在 android 范围,不是 buildTypeproductFlavor).