KMP 跨端代码共享 技术调研

KMP 跨端技术调研:

调研一期:

kotlin 写一个简单方法 greet() 返回一个字符串 当做共享方法

客户端

跨端形式

实验结果

Android 客户端

shared.lib 包

✔️

IOS 客户端

shared.framework 文件包

✔️

HarmonyOS 客户端

share.ts 文件组

✔️

前端 H5 网页 小程序 快应用

share.js 文件

✔️

后端 服务端

share.jar 包文件

✔️

Windows 客户端

shared.dll 文件

调研二期:

根据客户端的参数 可以是一个 int 值 share 侧做简单计算 再返回给客户端

客户端

跨端形式

实验结果

Android 客户端

shared.lib 包

✔️

IOS 客户端

shared.framework 文件包

✔️

HarmonyOS 客户端

share.ts 文件组

✔️

前端 H5 网页 小程序 快应用

share.js 文件

✔️

后端 服务端

share.jar 包文件

✔️

Windows 客户端

shared.dll 文件

首先为什么有这样的技术调研

--目前公司有以下几种客户端 分别为

  • 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 的产物

说下步骤

  1. jvm { compilations.all { kotlinOptions.jvmTarget = "1.8" // 显式设置Java 8 } } // 添加 JVM 目标

  1. 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" // 可选,设置主入口类 ) } }

  1. ./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 的集成方法


KMP 跨端代码共享 技术调研
https://nicestars.net//archives/wei-ming-ming-wen-zhang
作者
NiceStars
发布于
2025年04月01日
更新于
2025年04月12日
许可协议