处理Proguard,MultiDex,测试和产品口味时,有什么好的策略?

Ant*_*ony 6 android proguard gradle android-productflavors android-multidex

我有一个引用~100K方法的应用程序,最小Sdk = 16

这是2个组装选项:

  • Proguard将这一系列方法缩减为仅44K方法
  • 使用Multi Dex

现在我有一些常见的用例:

  1. 在模拟器和设备上运行和调试
    • 它需要尽可能快
  2. 做测试(集成和UI)
    • 它需要运行(我有一些问题运行Espresso与MultiDex)
  3. 制作Prod APK
    • 它需要尽可能可靠和缩小

你有人对组装策略有一些建议吗?

3/Prod

  • 使用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
        }
    }
Run Code Online (Sandbox Code Playgroud)

Ant*_*ony 3

基于我主要同意的@Muzikant的提议,我总结了我今天的愿景

  • MultiDex如果可以的话 尽量不要使用。
    • 测试库带来的方法开销可能会达到65K(所以使用MutliDex)
    • MultiDex 可能比 Proguard 进程更快(待检查),因此调试可能很有趣
  • 尝试使用与发布APK最接近的APK进行测试

我的建议是:

  1. 因为有 3 个构建案例,所以只需创建 3 个 buildTypes :

    • 发布
    • 调试
    • 验证(测试是保留字)
  2. 使用2种口味:

    • minSdkVersion与您的应用程序一起发布的一个
    • 一个用于开发,使用更新的minSdkVersion(更快的构建,更多的测试功能,更容易使用 espresso...)
  3. 不要为了调试而混淆

  4. 为了在测试阶段使用 Proguard,Gradle DSL 的特定关键字是必要的 testProguardFile('proguard-rules-test.pro')

  5. 指向将用于调试的构建 testBuildType = "validation"

  6. 对测试进行混淆(至少对于 CI 系统上的 UI 系统和功能测试)

  7. 仅在发布时使用优化 Proguard 规则getDefaultProguardFile('proguard-android-optimize.txt'),在测试和调试时仅使用getDefaultProguardFile('proguard-android.txt')

我的 Proguard 文件的架构如下:

  1. 一个要发布 proguard-rules-release.pro的主文件,其中包括一组专用的 Proguard 文件,其中包含-include proguard-rules-fabric.pro

  2. 用于调试 的第二个文件proguard-rules-debug.pro,其中包括proguard-rules-release.pro

  3. 三分之一的文件用于 禁用混淆的调试 proguard-rules-dontobfuscate.pro

  4. 第四份测试 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')
        }
    }
...
}
Run Code Online (Sandbox Code Playgroud)

我还有一些未解决的问题需要解决:

  • 如何使用 Android Studio 的自动调试签名进行验证构建?(但我不确定影响)

  • proguardFiles当我拥有包含调试的属性时,我仍然需要在验证 BuildType 中添加属性testProguardFile('proguard-rules-test.pro')