能否在通用KMP模块中集成带平台依赖的原生库?
可以整合为跨双平台的KMP通用模块
完全可以实现这个需求,核心是利用Kotlin Multiplatform的多源集特性,封装平台特定的原生库依赖,同时在公共代码层提供统一接口供上层KMP应用调用。具体实现步骤如下:
1. 定义跨平台公共接口
在KMP模块的commonMain源码集里,抽象出A库对外提供的所有能力,定义统一的Kotlin接口。这样上层应用只需要依赖这个接口,无需关心底层平台实现:
interface ALibrary { fun doBusinessLogic(): String fun processRawData(input: ByteArray): ByteArray // 其他需要暴露的方法 }
2. Android平台封装实现
在androidMain源码集里完成A.so和B.so的加载与接口绑定:
- 将A.so、B.so放入
src/androidMain/jniLibs下对应架构的子目录(如arm64-v8a、x86_64) - 通过JNI绑定原生接口,先加载依赖的B库,再加载A库,最后实现公共接口:
class AndroidALibrary : ALibrary { init { System.loadLibrary("B") System.loadLibrary("A") } override fun doBusinessLogic(): String { return nativeDoBusinessLogic() } override fun processRawData(input: ByteArray): ByteArray { return nativeProcessRawData(input) } // 声明JNI方法 private external fun nativeDoBusinessLogic(): String private external fun nativeProcessRawData(input: ByteArray): ByteArray }
- 若A、B库需要Android权限或配置,在
androidMain的AndroidManifest.xml中补充对应内容。
3. iOS平台封装实现
在iosMain源码集里完成A.framework和B.framework的集成与接口调用:
- 将A.framework、B.framework放入
src/iosMain/frameworks目录 - 在模块的gradle配置中嵌入依赖的framework,并通过cinterop生成Kotlin与Objective-C/Swift的绑定:
首先创建src/nativeInterop/cinterop/A.def文件:
language = Objective-C framework = src/iosMain/frameworks/A.framework headers = A.h
然后在gradle中配置cinterop和framework嵌入:
kotlin { ios { binaries { framework { baseName = "YourKMPWrapper" embedBinaries.add(file("src/iosMain/frameworks/B.framework")) embedBinaries.add(file("src/iosMain/frameworks/A.framework")) } } } sourceSets { iosMain.dependencies { implementation(interop("A")) } } }
- 实现公共接口,直接调用A.framework的原生方法:
class IosALibrary : ALibrary { override fun doBusinessLogic(): String { return A.doBusinessLogic() } override fun processRawData(input: ByteArray): ByteArray { return A.processRawData(input) } }
4. 提供平台实例工厂
在commonMain中定义expect工厂类,用于上层应用获取对应平台的A库实例:
expect class ALibraryFactory { fun create(): ALibrary }
然后在androidMain和iosMain中分别实现actual类:
// Android端实现 actual class ALibraryFactory actual constructor() { actual fun create(): ALibrary = AndroidALibrary() } // iOS端实现 actual class ALibraryFactory actual constructor() { actual fun create(): ALibrary = IosALibrary() }
上层KMP应用只需通过ALibraryFactory().create()获取实例,即可调用统一接口。
5. 构建与发布配置
- Android端:在gradle中配置
ndk.abiFilters,确保jniLibs的架构覆盖应用支持的设备 - iOS端:确认framework包含模拟器(x86_64)和真机(arm64)架构,若为拆分架构需区分构建变体
- 将整个KMP模块发布为Maven依赖,方便后续KMP应用直接引入使用
内容的提问来源于stack exchange,提问作者Maxim Sergeev
相关产品推荐
相关产品推荐

