KMP 跨端代码共享 技术调研
KMP 跨端技术调研:
调研一期:
kotlin 写一个简单方法 greet() 返回一个字符串 当做共享方法
调研二期:
根据客户端的参数 可以是一个 int 值 share 侧做简单计算 再返回给客户端
首先为什么有这样的技术调研
--目前公司有以下几种客户端 分别为
Android 客户端
IOS 客户端
HarmonyOS 客户端
微信小程序
支付宝小程序
快应用
网页端
然后接入的引擎又都是一致的 接入引擎的返回数据也都是一致的 但是各个客户端都自己实现的代码 这当然是历史遗留问题 所以现在寻求机会修改一下
修改这个问题 是个大工程 底座得选好,底座不选好的话后面很多事情都没法执行下去!
那首先就是第一件事情,对底座进行技术选型.
核心思路是一套代码多段共用 代码可以以库的形式 供各个客户端调用
初步的调研思路
KMP
JS
Python
API
经过一下午的尝试 目前来看 KMP 方式行得通 满足了我对新技术的全部想法 下面来展开说说
先简单做个排除法吧 !
1.首先排除 API 让后端写 API 并行受不了不说,没网 App 直接就用不了!直接 pass
2.JS 前端是可以用,但是客户端如何使用 没有研究过,并且后端是否能直接调用 JS 代码还未知,所以暂时不排除
3.python python 虽然也是跨端语言,但和 JS 的问题一样,客户端和后端有没有转化库还不好说,但也不能立即排除
还剩一个 KMP 本来不知道有这个东西的,但现在是 AI 时代,我把我的想法告诉大模型之后,大模型就给了我这个回复,原本大模型还给了我使用 C++ 来写的建议呢 本来以为又要学会一门语言了 现在给我退了 KMP
是使用 kotlin 开发的一个新的跨端平台,又是 kotlin 又是跨平台那我当然要试试了!
尝试之前先搞清楚什么 KMP
来看看 GPT 给的概括:
Kotlin Multiplatform 是 JetBrains 提供的一套跨平台开发方案,允许使用同一套 Kotlin 代码同时面向多个平台(如 Android、iOS、JS/Browser、桌面等)进行开发。它通过将通用业务逻辑抽离到一个共享模块中,并针对不同平台进行各自的实现或适配,从而减少重复编码,降低维护成本,并让开发者在多端上享受 Kotlin 带来的简洁与安全性。
看看! 绝了...就是我想要解决的问题呀! 要共享的代码也是来自 kotlin 可以减少很多工作量!
那就试试!
根据汇总各方面文档讲讲我探索的步骤
Android 客户端 and IOS 客户端
首先 AndroidStudio 先安装 KMP 插件
等插件安装好了之后 新建项目
选这俩没啥太大区别 就是 Android 和 IOS 能不能直接运行的问题 个人建议选 kotlin Multiplatform App 因为提供了调试的入口 方便调试
接着进行项目配置
注意:IOS framework distribution 这个选项 选 CocoaPods dependency manager 暂时对 IOS 不太了解 所以不太明白 但是这么选是我实践出来的
配置成功之后就可以进入项目
接着打开 shared 的 build.gredle 文件
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.kotlinCocoapods)
alias(libs.plugins.androidLibrary)
}
kotlin {
androidTarget {
compilations.all {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
iosX64()
iosArm64()
iosSimulatorArm64()
cocoapods {
summary = "Some description for the Shared Module"
homepage = "Link to the Shared Module homepage"
version = "1.0"
ios.deploymentTarget = "16.0"
podfile = project.file("../iosApp/Podfile")
framework {
baseName = "shared"
isStatic = true
}
}
sourceSets {
commonMain.dependencies {
//put your multiplatform dependencies here
}
commonTest.dependencies {
implementation(libs.kotlin.test)
}
}
}
android {
namespace = "com.nicestars.mainlib"
compileSdk = 34
defaultConfig {
minSdk = 24
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
看上面代码已经建立好了 Android 和 IOS 的相关信息了
那么接下来开始写一个共同方法
在 shared Module 的 commonMain 的 Greeting 类里面修改一个方法
fun greet(): String {
return "[Hello Word]"
}
嗯!经典的 helloWod 就可以了
开始测试
看代码结构 Android 就不用试了 因为就是一个 lib 工程
接下来试试 IOS
将编译出来的 build->cocoapods 文件夹下的 shared.framework 文件夹所有文件全部放在 XCode 里面去
使用核心代码如下
经过编译和真机运行是可以运行的
开始尝试后端
后端和 Android 差不多 比较简单 因为都是 jvm 的产物
说下步骤
jvm { compilations.all { kotlinOptions.jvmTarget = "1.8" // 显式设置Java 8 } } // 添加 JVM 目标
tasks.register<Jar>("toJar") { archiveBaseName.set("test_jar") archiveVersion.set("1.0.1") from(kotlin.targets.getByName("jvm").compilations.getByName("main").output.allOutputs) manifest { attributes( "Main-Class" to "com.example.MainKt" // 可选,设置主入口类 ) } }
./gradlew :shared:toJar
将 jar 包给到后端的开发 即可
后端的使用
引入:
使用:
接下来尝试前端和鸿蒙
前端要使用 js 代码做为代码库 具体操作方式为
工程 build.gradle 文件新增配置:
//kotlin下面新增
js(IR) {
moduleName = "kmp-shared"
browser {
binaries.executable() // 改为生成可执行文件
commonWebpackConfig {
outputFileName = "kmp-shared" // 可选,指定输出文件名
}
}
nodejs()
generateTypeScriptDefinitions() // 生成 d.ts 文件的关键配置
}
//sourceSets下面新增
val jsMain by getting {
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-js")
}
}
执行 build 之后会 shared/build 文件夹下会新增 compileSync 文件夹
将 kmp-shared.js 给前端使用
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Test Greeting</title>
</head>
<body>
<script src="shared.js"></script>
<script>
// 在全局可以通过 shared.com.nicestars.lib.Greeting 访问 Greeting 类
const greeting = new shared.com.nicestars.lib.Greeting();
const result = greeting.greet(); // 调用 greet() 方法
console.log(result); // 输出 "Hello,word"
</script>
</body>
</html>
结果如下
将如图所示 文件给 DevEco-Studio
然后 index.ets 代码:
import { hilog } from '@kit.PerformanceAnalysisKit';
import router from '@ohos.router';
import { PushManager } from '../util/RouterUtil';
import * as libShared from "../kmp-shared";
@Entry
@Component
struct Index {
@State private greetingText: string = '';
onInit() {
// 页面初始化时,创建 Greeting 实例并获取问候字符串
const greeting = new libShared.com.nicestars.lib.Greeting();
this.greetingText = greeting.greet();
}
aboutToAppear(): void {
this.onInit()
}
build() {
RelativeContainer() {
Button(this.greetingText)
.id('bt_pay')
.fontSize(12)
.backgroundColor("#2bc5d6")
.fontWeight(FontWeight.Normal)
.alignRules({
top: { anchor: '__container__', align: VerticalAlign.Top },
left: { anchor: '__container__', align: HorizontalAlign.Start },
right: { anchor: '__container__', align: HorizontalAlign.End },
})
.margin({ left: 16, right: 16, top: 60 })
.onClick(() => {
const greeting = new libShared.com.nicestars.lib.Greeting();
console.log('NiceStars',greeting.greet())
console.log('NiceStars',this.greetingText)
})
}.backgroundColor("#90000000")
.height('100%')
.width('100%')
}
}
至此 HarmonyOS 也可调用
调研工作结束
如果做到 windows 的话 再补一下 Windows 的集成方法