You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何先对Android库执行Proguard/R8再处理主应用,模拟外部依赖场景?

问题:本地依赖Android库时模拟外部依赖的Proguard/R8混淆效果

我正在开发一款闭源Android库,同时维护一个依赖该库的Android应用。目前库的release构建能生成符合预期的混淆.aar,且consumer-rules.pro配置正确,外部应用依赖该aar时功能正常。但当应用通过implementation project(':my-lib')本地依赖库时,Proguard/R8会将库和应用源码聚合后统一处理,导致库中部分该混淆的代码未混淆、该保留的被移除,自定义mapping也不生效。

我希望在本地依赖的情况下,实现和外部应用依赖aar完全一致的效果,不想频繁发布测试包来验证。

项目关键文件结构

my-project/
├─ my-app/
│  ├─ ...
│  ├─ build.gradle
│  ├─ proguard-rules.pro
├─ my-lib/
│  ├─ ...
│  ├─ build.gradle
│  ├─ custom-mapping.txt
│  ├─ consumer-rules.pro
│  ├─ proguard-rules.pro

my-app的build.gradle

android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}
...
dependencies {
    ...
    implementation project(':my-lib')
}

my-lib的build.gradle

android {
    defaultConfig {
        ...
        consumerProguardFiles "consumer-rules.pro"
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

my-lib的proguard-rules.pro

-applymapping "custom-mapping.txt"

# Place every obfuscated class in a single package
-flattenpackagehierarchy 'com.mycompany.mylib.obfuscated'

# Do not attempt to shrink the code when building this library as a standalone, otherwise all of
# the code will get stripped, ending up with an empty aar file
-dontshrink

# Here are my keep rules
...

my-lib的consumer-rules.pro

# Some keep rules related to Android internal classes that I rely on in my library

# Field that shouldn't be stripped if the class is present
-keepclassmembers class com.mycompany.mylib.obfuscated.z.z { # <-- the z.z comes from the custom mapping I'm applying to ensure it's always obfuscated the same way
    # Fields that I want to keep and that would be shrunk without specifying it
    ...
}

解决方案

1. 直接依赖库的release预混淆产物

修改my-app的依赖配置,指定使用my-lib已经完成混淆的release变体,而非合并源码重新处理:

dependencies {
    ...
    implementation project(path: ':my-lib', configuration: 'release')
}

这种方式和外部应用依赖aar的行为完全一致,Gradle会直接使用my-lib构建好的混淆aar,避免源码聚合后的统一混淆。

2. 配置构建类型的依赖对齐(可选)

如果需要在应用的debug构建中也使用库的release产物,或者统一构建类型的依赖规则,先在my-lib的build.gradle中开启全变体发布:

android {
    publishNonDefault true // 默认仅发布release变体,开启后会发布所有构建类型产物
}

然后在my-app中针对不同构建类型指定依赖:

dependencies {
    debugImplementation project(path: ':my-lib', configuration: 'release')
    releaseImplementation project(path: ':my-lib', configuration: 'release')
}

3. 确保自定义mapping生效

当依赖预混淆的库时,my-lib的-applymapping规则已经在自身release构建阶段生效,应用的Proguard只会加载库的consumer-rules.pro规则,不会修改库已有的混淆结果,完美模拟外部依赖场景。

4. 修复依赖传递问题

依赖预混淆aar时如果出现依赖缺失,可将my-lib中的implementation依赖改为api,确保依赖能自动传递给my-app:

// 在my-lib的build.gradle中
dependencies {
    api 'com.some.dependency:xxx:1.0.0'
}

内容的提问来源于stack exchange,提问作者Paul-Etienne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 00:02:47