在处理 Proguard、MultiDex、测试和产品风味时,啥是好的策略?
Posted
技术标签:
【中文标题】在处理 Proguard、MultiDex、测试和产品风味时,啥是好的策略?【英文标题】:What is the good strategy when dealing with Proguard, MultiDex, Testing and Product Flavors?在处理 Proguard、MultiDex、测试和产品风味时,什么是好的策略? 【发布时间】:2016-08-05 16:39:53 【问题描述】:我有一个引用 ~ 100K 方法的应用,其中 min Sdk = 16
这里有两种组装方式:
Proguard 将这组方法缩减到只有 44K 个方法 使用多敏捷现在我有一些常见的用例:
-
在模拟器和设备上运行和调试
要求尽可能快
进行测试(集成和 UI)
它需要运行(我在使用 MultiDex 运行 Espresso 时遇到了一些问题)
制作 Prod APK
它要求尽可能可靠和缩小
你们对组装策略有什么建议吗?
3/ 产品
使用 Proguard 减小 APK 大小 使用 Proguard 进行混淆 尽量不要使用 Multidex(可能会失败)2/ 测试
使用 minSdkVersion 21(我读到从 21 开始启用 pre-dexing,这样可以节省时间) ???1/ 调试
使用 minSdkVersion 21(我读到从 21 开始启用 pre-dexing,这样可以节省时间) ???这是 Gradle 文件:
productFlavors
dev
minSdkVersion 21
multiDexEnabled ???
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
prod
// The actual minSdkVersion for the application.
minSdkVersion ANDROID_BUILD_MIN_SDK_VERSION
multiDexEnabled false
defaultConfig
applicationId "xxxx"
targetSdkVersion ANDROID_BUILD_TARGET_SDK_VERSION
minSdkVersion ANDROID_BUILD_MIN_SDK_VERSION
versionCode ANDROID_BUILD_VERSION_CODE
versionName ANDROID_BUILD_APP_VERSION_NAME
buildTypes
release
debuggable false
ext.enableCrashlytics = true
renderscriptOptimLevel 3
signingConfig android.signingConfigs.release
zipAlignEnabled true
minifyEnabled true
// shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
debug
debuggable true
renderscriptOptimLevel 3
applicationIdSuffix ".debug"
versionNameSuffix "debug"
minifyEnabled false
【问题讨论】:
【参考方案1】:根据@Muzikant 的提议,我主要同意,我总结了我今天的愿景
如果可以,尽量不要使用MultiDex
。
可能会碰巧达到 65K 的数量,方法是测试库带来的开销(所以使用 MutliDex)
MultiDex 可能会比 Proguard 进程更快(待检查),因此调试可能会很有趣
尝试使用与发布 APK 最接近的 APK 进行测试
我的建议是:
因为有 3 个构建案例,所以只需要 3 个构建类型:
发布 调试 验证(test是保留字)使用两种口味:
与您的应用程序的minSdkVersion
一起发布
还有一款用于开发,使用更新的 minSdkVersion
(构建速度更快,测试功能更多,espresso 更易于使用...)
不要混淆调试
为了在测试阶段使用 Proguard,Gradle DSL 的特定关键字是必要的testProguardFile('proguard-rules-test.pro')
使用testBuildType = "validation"
指出将用于调试的构建
对测试进行混淆处理(至少对于您的 CI 系统上的 UI 系统和功能测试)
仅对发布getDefaultProguardFile('proguard-android-optimize.txt')
使用优化Proguard规则,测试和调试仅使用getDefaultProguardFile('proguard-android.txt')
我的 Proguard 文件的架构如下:
release proguard-rules-release.pro
的一个主文件,其中包括一组专用的 Proguard 文件,-include proguard-rules-fabric.pro
debug proguard-rules-debug.pro
的一秒文件,其中包括 proguard-rules-release.pro
三分之一文件用于调试 proguard-rules-dontobfuscate.pro
禁用混淆
用于测试 proguard-rules-test.pro
的第四个文件,其中包括proguard-rules-debug.pro
和测试所需的规则
这是 Gradle 文件:
android
...
compileSdkVersion ANDROID_BUILD_SDK_VERSION
buildToolsVersion ANDROID_BUILD_TOOLS_VERSION
productFlavors
// Define separate dev and prod product flavors.
dev
// dev utilizes minSDKVersion = 21 to allow the Android gradle plugin
// to pre-dex each module and produce an APK that can be tested on
// Android Lollipop without time consuming dex merging processes.
minSdkVersion 21
multiDexEnabled false
prod
// The actual minSdkVersion for the application.
minSdkVersion ANDROID_BUILD_MIN_SDK_VERSION
multiDexEnabled false
defaultConfig
applicationId "x.y.app.z"
targetSdkVersion ANDROID_BUILD_TARGET_SDK_VERSION
minSdkVersion ANDROID_BUILD_MIN_SDK_VERSION
versionCode ANDROID_BUILD_VERSION_CODE
versionName ANDROID_BUILD_APP_VERSION_NAME
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
// point thge build for testing
testBuildType = "validation"
buildTypes
release
debuggable false
ext.enableCrashlytics = true
renderscriptOptimLevel 3
signingConfig android.signingConfigs.release
zipAlignEnabled true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules-release.pro'
debug
debuggable true
renderscriptOptimLevel 3
applicationIdSuffix ".debug"
versionNameSuffix "debug"
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-debug.pro', `proguard-rules-dontobfuscate.pro`
validation.initWith(debug)
validation
signingConfig android.signingConfigs.release
debuggable false
renderscriptOptimLevel 3
applicationIdSuffix ".test"
versionNameSuffix "test"
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-debug.pro'
testProguardFile('proguard-rules-test.pro')
...
我还有一些未解决的问题:
如何使用 Android Studio 的自动调试签名进行验证构建? (但我不确定影响)
我仍然需要在验证 BuildType 中添加 proguardFiles
属性,而我的 testProguardFile('proguard-rules-test.pro')
包含调试!
【讨论】:
可能为第一个打开点添加validation.initWith(buildTypes.debug)(待检查) 我明白了这一点“仅将优化 Proguard 规则用于发布 getDefaultProguardFile('proguard-android-optimize.txt'),用于测试和调试只需使用 getDefaultProguardFile('proguard-android.txt') “ 给出。为什么我们不使用优化代码运行测试?我已经对我的代码进行了混淆测试,但我遇到了优化代码的问题。【参考方案2】:为了避免多重索引,我在调试和发布版本上都使用了 proguard。
我的build.gradle
文件如下所示:
debug
minifyEnabled true
proguardFiles 'proguard_debug.pro'
signingConfig signingConfigs.debug
debuggable true
release
minifyEnabled true
proguardFiles 'proguard_release.pro'
signingConfig signingConfigs.release
debuggable false
为了尽量减少调试和发布之间的差异,并允许正确调试调试版本,proguard_debug.pro
文件包含以下 proguard 说明:
-include proguard_release.pro
-dontobfuscate
-dontoptimize
-keep class my.package.name.** *;
这样,我只维护一个 proguard 配置(在 proguard_release.pro
中),调试版本是使用相同的配置构建的,但不会混淆代码。
该配置解决了所有提到的问题:
-
不需要多索引(所以是否与 API 一起使用没有两难选择)
21+,你可以使用 Espresso)
调试版本和发布版本相同,只是调试版本不会混淆您的代码
【讨论】:
好的,很好。请注意,它也可能存在由混淆引起的问题!然而,构建 apk 对于调试和测试来说真的很慢。你能适应这种延迟吗? 考虑到替代方案,这对我来说是最好的解决方案。混淆不是问题,因为调试 proguard 配置具有 -dontobfuscate 标志 是的,我只是说混淆可能会给应用程序带来错误。这也很好测试 当代码被混淆和优化时,是否可以使用对象注入运行检测测试用例?以上是关于在处理 Proguard、MultiDex、测试和产品风味时,啥是好的策略?的主要内容,如果未能解决你的问题,请参考以下文章
在 Android 应用程序中使用 MultiDex 运行 ProGuard 两次,只有第二次出现警告/注释?
Android ProGuard +MultiDex 导致 ClassNotFoundException
使用 Multidex 的 Android proguard