Kotlin Multiplatform - 下一代全平台开发技术

code小生,一个专注 Android 领域的技术平台

公众号回复 Android 加入我的安卓技术群

作者:dengyin2000
链接:https://www.jianshu.com/p/80eddf62a99a
声明:本文已获dengyin2000授权发表,转发等请联系原作者授权

多平台开发痛点

Kotlin Multiplatform 最重要的目标是在多平台上共享代码,现在支持的平台有JVM,Android,Javascript,iOS、Linux、Windows、Mac等,几乎覆盖所有的平台。设想下现在移动优先的策略,一个公司至少要做 Android、iOS、WAP、小程序平台。其中 Data Model,接口调用,业务逻辑等这些代码各个平台都需要用不同的语言实现。这样做了很多重复的工作,而且你需要招更多人,公司需要为更多人支付更多的薪水。

640?wx_fmt=other
different platform dev

Kotlin Multiplatform简介

640?wx_fmt=other
Kotlin multiplatform

Kotlin Multiplatform 并不是把你写的代码在各个平台上翻译一遍,这样做会有很多限制。各个平台会有自己的一些平台特性的功能。Kotlin Multiplatform能让你共享尽可能多的代码,但是也提供调用一些平台特有的API(expect/actual语法)。这里我们可以看到我们使用Kotlin/JVM来生成安卓和后端的Java代码,使用Kotlin/Native来生成Objective-C代码给到iOS,使用Kotin/JS生成javascript代码。

Common Module

640?wx_fmt=other
Common Moudle

你可以把多个平台通用的代码提取到Common Module,比如DTO、API调用,一些工具类、还有业务逻辑。当然你也可以直接使用一些已经支持Multiplatform的第三方类库:

  • Kotlin Standard Library

  • Ktor client 网络接口调用(基于协程)

  • Kotlin serialization 序列化

  • Mockk Mock类库

  • Kotlinx-io io类库

  • Kotlinx-json json库

支持多平台的第三方类库现在也是迅猛发展,会有越来越多Java、Kotlin类库会转成支持 Multiplatform。

Demo

官方的demo可以看这里:http://kotlinlang.org/docs/tutorials/native/mpp-ios-android.html。怎么搭建环境创建项目这里就不详细说了:

640?wx_fmt=other

project

Demo还是非常简单的,就是创建一个字符串,然后拼接上平台返回的一段字符串。这里我们来做一个相对复杂一点的示例,比如我们要调用一个网络接口,返回一个天气信息的json string,然后我们把json string序列化成对象,然后在android iPhone界面上显示。

SharedCode项目gradle配置

apply plugin: 'kotlin-multiplatform'
apply plugin: 'kotlinx-serialization'

kotlin {
    targets {
        final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") \
                              ? presets.iosArm64 : presets.iosX64

        fromPreset(iOSTarget, 'ios') {
            compilations.main.outputKinds('FRAMEWORK')
        }

        fromPreset(presets.jvm, 'android')
    }

    sourceSets {
        commonMain{
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serialization_version"
            }
        }

        androidMain {
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"
            }
        }
        iosMain{
            dependencies {
                implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
                implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:$serialization_version"
            }
        }
    }
}

我们在tagets里面定义了两种平台,分别是ios和android,当然默认的还有common模块用来放共享的代码。
在sourceSets里面我们定义了common, android, ios模块的依赖,这里我们依赖了kotlin标准库和kotlinx-serialization库。这里要注意下,同一个库在不同平台下依赖的artifactId可能会不一样。

Show me code

common.kt

expect fun httpGet(url:String):String


fun <T> convertJsonToObject(jsonString: String, serializer:DeserializationStrategy<T>):T {
    return JSON(strictMode = false).parse(serializer, jsonString)
}

fun getGuangZhouWeather():CityWeather {
    val jsonString = httpGet("http://t.weather.sojson.com/api/weather/city/101280101")
    println("jsonString: $jsonString")
    return convertJsonToObject(jsonString, CityWeather.serializer())
}

@Serializable
data class CityWeather(
        var time: String,
        var date: String,
        var message: String,
        var status: String,
        var cityInfo:CityInfo,
        var data: WeatherData

)

@Serializable
data class WeatherData(
        var shidu: String,
        var pm25: String,
        var pm10: String,
        var quality: String,
        var wendu: String,
        var ganmao: String,
        var yesterday:DayInfo,
        var forecast:MutableList<DayInfo>
)

这段common.kt的代码是在android和ios上共享的,注意第一行:

expect fun httpGet(url:String):String

我们用expect关键字定义了一个调用http请求的方法,传入一个字符串类型的url然后返回http response的字符串。这个expect关键字表示这个方法是需要每个平台各自实现的。
convertJsonToObject方法是调用kotlinx-serialization跨平台库把json string序列化成对象。
getGuangZhouWeather方法是先调用网络请求,然后把字符串序列化成CityWeather对象返回。

最后我们需要做的是在/androidMain/kotlin/actual.kt和/iosMain/kotlin/actual.kt文件实现在common.kt定义的httpGet方法。

Android实现

actual fun httpGet(url:String):String{
  return URI(url).toURL().readText()
}

iOS实现

actual fun httpGet(url:String):String{
  val urlWithString = NSURL.URLWithString(url)
  if (urlWithString != null) {
    val requestWithURL = NSMutableURLRequest.requestWithURL(urlWithString)
    val response: CPointer<ObjCObjectVar<NSURLResponse?>>? = null
    val error : CPointer<ObjCObjectVar<NSError?>>? = null
    val nsData = NSURLConnection.sendSynchronousRequest(requestWithURL, response, error)?.copy() as NSData
      println("nsData: $nsData, lenght: ${nsData.length}, desc: ${nsData.description}")
      println("response: $response")
      val string = NSString.stringWithCString(nsData.bytes() as CPointer<ByteVar>, encoding=NSUTF8StringEncoding)
      if (string != null) {
        return string
      }

  }

  return ""
}

如果你玩过Objective-c,你一定对上面的iOS实现的代码非常熟悉,这里的每个类都跟Objecttive-c都能对应上。实现项目可以通过写Kotlin代码来Objective-C代码。这就是Kotlin/Native的能力。

640?wx_fmt=other

Kotlin/Native

Build

在项目顶层指定gradlew命令,编译项目。

./gradlew clean build
640?wx_fmt=other
image.png

编译完成之后你可以看到

640?wx_fmt=other
build

运行Android & iPhone App

调用其实也很简单,android 和 iphone调用getGuangZhouWeather方法,然后显示温度。

640?wx_fmt=other
Run app

运行iPhone的时候要注意,因为这里要调用http接口,所以你需要设置一下security settings,如下:

640?wx_fmt=other
security setting

完整代码请看:
https://github.com/dengyin2000/mpp-iOS-Android

Reference:

KotlinConf 2018 - Effective Multiplatform Kotlin Development by Marcin Moskala
官方文档

640

分享技术我是认真的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kotlin Multiplatform 是一种由 JetBrains 开发的跨平台开发框架。它允许开发人员使用 Kotlin 语言编写代码,然后在多个平台上运行,包括 Android、iOS、Web 等。与传统的跨平台解决方案相比,Kotlin Multiplatform 提供了更高的灵活性和性能。 Kotlin Multiplatform 的核心思想是共享代码。开发人员可以编写一个通用的 Kotlin 模块,其中包含与平台无关的业务逻辑和算法。然后,他们可以根据不同的目标平台,编写平台特定的代码。这样,开发人员可以在不同平台之间共享核心逻辑,减少了重复代码的编写,并且保持了一致性。 Kotlin Multiplatform 目前已经应用于许多项目中。对于 Android 开发人员来说,它提供了更好的性能和开发体验。它允许开发人员在 Android 和 iOS 上使用相同的 Kotlin 代码库,从而加快了开发速度和代码复用。对于 iOS 开发人员来说,Kotlin Multiplatform 可以通过共享核心业务逻辑来简化跨平台开发,并且可以与现有的 Objective-C 或 Swift 代码无缝集成。 总之,Kotlin Multiplatform 是一个强大的跨平台开发框架,可以大大简化和提高开发人员的工作效率。它同时适用于 Android 和 iOS 开发,并且允许开发人员在不同平台之间共享核心逻辑。在未来,我们可以预见 Kotlin Multiplatform 将会在跨平台开发领域发挥更大的作用,并且有望成为开发人员的首选解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值