文章目录
平台差异化代码的使用场景
由于 KMM 运行在各平台时,实际上是翻译成了各平台专用的库,如:Android 上就会将共享模块编译成 Dalvik Bytecode 然后打包成 AAR 文件,而 iOS 上会打包成 Apple Framework,所以,一些平台相关的、不可共享的具体实现代码,就必须利用各平台的 API 来实现
举个简单的例子,公共模块有一个统一的业务逻辑——获取手机型号,控制逻辑可以在 KMM 的 common 代码库中实现,且它并不关系具体的实现逻辑,而实际需要获取手机型号字符串的方法,Android 需要调用 android.os.Build.MODEL
获取,而 iOS 需要通过 UIDevice.current.model
来获取
类似的平台强相关功能,就需要在 KMM 中利用平台差异化代码实现
差异化代码的基本实现
这里需要再次引用 Kotlin 官方的一张图
如图所示,在 KMM 中,Common 库中可以将需要差异化实现的 class
或 fun
使用 expect
关键字修饰,expect
字面意思是:期望,这里代表需要各平台具体实现,之后在 Android、iOS 对应的库中,再使用 actual
关键字来创建对应的 class
及 fun
,即可完成差异化代码的构建,在 App 中调用 Common 中使用 expect
修饰的内容时,将自动执行不同平台的 actual
内容
Demo 及注意点
expect & actual 实现方式
这种方式是官方推荐的一种平台差异化功能实现方式,实际操作时也比较简单
在 Common 中建立一个 expect 类或 Top-Level 方法
如图所示,创建 expect
类或方法,有点类似 Kotlin 和 Java 中的 interface
在完成基本的代码以后,此时可以看到 IDE 已经报错了,提示没有找到给 Android 使用的 JVM 实现,以及给 iOS 使用的 Native 实现
完成 actual 实现
此时不要使用 Option + Enter(Windows:Alt + Enter) 来靠 IDE 自动创建, 需要分别在 androidMain 和 iosMain 目录中,创建与 expect
内容包名、类名、方法签名(包括方法名、参数类型及名称)完全一致的 actual
内容,否则会报错
Android 示例:
// AndroidImpl.kt
package com.coderyuan.myfirstkmm
import android.util.Log
actual class PlatformSpecific {
actual fun method1(): String {
return "Android-Method1"
}
actual fun method2() {
println("Android-Method2")
}
}
actual fun platformTestFunc(v1: Int, v2: String) {
Log.i("Android-Func", "v1: $v1, v2: $v2")
}
iOS 示例:
// iOSImpl.kt
package com.coderyuan.myfirstkmm
import platform.Foundation.NSLog
actual class PlatformSpecific {
actual fun method1(): Strin