排除发布构建类型的资产
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-lib
和 great-lib-debug
),并且在 debugCompile
和 releaseCompile
中有依赖关系,但是我宁愿避免这种情况并发布一个版本)
我最后做了以下事情:
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) 用于 debug
和 release
,一个 (src/debug/assets) 仅用于调试版本。
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
。
其他提到 packagingOptions
和 aaptOptions
的答案树错了,因为它们的范围是 all 变体(它们在 android
范围,不是 buildType
或 productFlavor
).
我正在使用 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-lib
和 great-lib-debug
),并且在 debugCompile
和 releaseCompile
中有依赖关系,但是我宁愿避免这种情况并发布一个版本)
我最后做了以下事情:
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) 用于 debug
和 release
,一个 (src/debug/assets) 仅用于调试版本。
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
。
其他提到 packagingOptions
和 aaptOptions
的答案树错了,因为它们的范围是 all 变体(它们在 android
范围,不是 buildType
或 productFlavor
).