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

Gradle多Flavor项目中如何避免重复编译原生代码

解决多Flavor项目中原生代码重复编译的问题

刚好之前踩过这个坑,给你几个实用的解决方案,能让通用原生代码只编译一次:

方案1:把通用代码放到main共享目录

这是最简单直接的方式——Android Gradle插件默认会把src/main/下的资源、代码作为所有Flavor的共享部分。你只需要:

  • 将通用的C/C++代码移到src/main/jni/目录下
  • 如果有预编译的.so库,放到src/main/jniLibs/对应的ABI子目录里

这样Gradle在构建任何Flavor时,都会复用main目录下原生代码的编译结果,不会重复编译。

方案2:自定义共享SourceSet

如果不想把通用代码放到main里(比如想和Flavor专属代码明确区分),可以单独定义一个共享的SourceSet,让所有Flavor继承它:

在app模块的build.gradle中添加配置:

android {
    // 先定义一个存放通用原生代码的SourceSet
    sourceSets {
        commonNative {
            jni.srcDirs = ['src/commonNative/jni']
            // 如果有头文件或预编译库,也可以指定:
            // jniLibs.srcDirs = ['src/commonNative/jniLibs']
        }

        // 让每个Flavor都继承这个共享SourceSet
        flavor1 {
            jni.srcDirs += commonNative.jni.srcDirs
            jniLibs.srcDirs += commonNative.jniLibs.srcDirs
        }
        flavor2 {
            jni.srcDirs += commonNative.jni.srcDirs
            jniLibs.srcDirs += commonNative.jniLibs.srcDirs
        }
        // 其他Flavor同理配置
    }
}

配置完成后,Gradle会将commonNative目录下的代码视为所有Flavor的共享依赖,仅编译一次,所有Flavor复用这个编译产物。

方案3:预编译通用原生代码

如果你的通用原生代码比较稳定,不需要频繁修改,可以提前编译成.so库,然后让所有Flavor直接依赖预编译产物:

  1. 用NDK Build或CMake单独编译通用代码,生成对应ABI的.so文件
  2. 在项目中创建一个共享目录(比如libs/common/),把.so文件按ABI分类存放(比如libs/common/armeabi-v7a/libcommon.so)
  3. 在build.gradle中指定这个目录为所有Flavor的jniLibs来源:
android {
    sourceSets {
        main {
            jniLibs.srcDirs += ['libs/common']
        }
    }
}

这种方式完全避免了重复编译,适合代码变动少的场景。

额外小技巧:用宏处理少量Flavor差异

如果通用代码里有极少数需要根据Flavor调整的逻辑,不用拆分代码,直接用宏定义处理即可。比如在CMakeLists.txt中根据当前Flavor注入宏:

# 获取当前构建的Flavor(需要在Gradle中传递参数)
set(FLAVOR ${CMAKE_FLAVOR})

if(${FLAVOR} STREQUAL "flavor1")
    add_definitions(-DFLAVOR_SPECIAL=1)
else()
    add_definitions(-DFLAVOR_SPECIAL=0)
endif()

然后在Gradle中传递Flavor参数:

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                arguments "-DCMAKE_FLAVOR=${productFlavors.name}"
            }
        }
    }
}

这样在C/C++代码里就能用#ifdef FLAVOR_SPECIAL来处理差异,大部分代码依然保持共享,只编译一次。

内容的提问来源于stack exchange,提问作者Joan P.S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:43:00