Kotlin跨平台开发(一)

Kotlin跨平台开发

  • 今天我们来简单介绍一下使用kotlin进行跨平台开发,使得一处代码,多处运行。

一、简介

首先,我摘取了一些官方文档上的基本介绍。

kotlin语言在一开始设计的时候就有一个明确的目标,那就是能够在所有平台上使用,能够使用kotlin开发任意平台的应用。同时kotlin还有一个重要的目标,就是能够在不同平台间共享代码。

kotlin不仅可以编译为jvm平台的字节码文件,还能够直接编译成二进制文件以及js文件。有了对 JVM、Android、JavaScript、iOS、Linux、Windows、 Mac 甚至像 STM32 这样的嵌入式系统的支持,Kotlin 可以处理现代应用程序的任何组件与所有组件。 这为代码与专业知识的复用带来了宝贵的收益,节省了工作量去完成更具挑战任务,而不是将所有东西都实现两次或多次。

它是如何工作的

总得来说,多平台并不是为所有平台编译全部代码。这个模型有其明显的局限性,我们知道现代应用程序需要访问其所运行平台的独有特性。Kotlin 并不会限制你只使用其中所有 API 的公共子集。 每个组件都可以根据需要与其他组件共享尽可能多的代码, 而通过语言所提供的 expect/actual 机制可以随时访问平台 API。

expect/actual

在一些情况下我们可能需要针对不同的平台编写不同的代码。这时我们需要通过expect关键字在公共代码部分定义需要在不同平台实现的类或者方法,然后在各平台对应的目录下通过actual关键字去实现对应的类或方法。如图中所示,在公共代码部分,writeLogMessage方法通过expect关键字定义。

image

然后我们需要在不同的平台中去实现该方法如js平台的实现:

image

jvm平台的实现:

image

多平台库依赖其他多平台库

二、项目搭建

(一)项目创建

这里建议使用最新的idea,虽然理论上项目使用gradle构建,用Android studio应该也是没问题的,但是idea自带项目骨架,还是方便不少。

1.使用idea新建项目,在kotlin项目中选择Multiplatform Library

image

image

image

小技巧:
  • 默认的项目构建依赖的gradle版本本地没有,需要下载,此时可终止任务,修改本地存在的较新版本的gradle。
  • 项目默认会构建macos平台,会下载相关依赖库,如果不需要macos平台可以终止任务后在build.gradle中移除macos相关配置

(二)项目结构

创建项目后会自动生成以下目录

image

commonMain目录是公共代码所在的目录

目录介绍
commonMain公共代码
commonTest公共测试代码
jsMainJs平台代码
jsTestJs平台测试代码
jvmMainjvm平台代码(Android)
jvmTestjvm平台测试代码
macosMainmacos平台代码
macosTestmacos平台测试代码
iosMainios平台代码
iosTestios平台测试代码

注:默认没有iOS目录,如果需要iOS平台需自行手动创建

commonMain内的结构和普通项目类似

image

(三)项目build.gradle

默认文件:

plugins {
    id 'org.jetbrains.kotlin.multiplatform' version '1.3.61'//配置kotlin多平台插件和版本
}
repositories {
    mavenCentral()//配置maven中央仓库
}
group 'com.example'//定义包所在组
version '0.0.1'//版本

apply plugin: 'maven-publish'//引用maven上传插件

kotlin {//用于配置需要构建的平台信息
    jvm()//构建jvm平台,输出jar包
    js {//构建js平台,输出js module
        browser {//构建适用于浏览器环境的js模块
        }
        nodejs {//构建适用于node环境的js模块
        }
        //由于nodejs和browser环境提供的API不同,所以需要区分。
    }
    // For ARM, should be changed to iosArm32 or iosArm64
    // For Linux, should be changed to e.g. linuxX64
    // For MacOS, should be changed to e.g. macosX64
    // For Windows, should be changed to e.g. mingwX64
    macosX64("macos")//构建macos平台,输出framework
    sourceSets {//源码设置
        commonMain {//公共代码目录
            dependencies {//公共代码需要的依赖
                implementation kotlin('stdlib-common')
            }
        }
        commonTest {//公共代码测试
            dependencies {
                implementation kotlin('test-common')
                implementation kotlin('test-annotations-common')
            }
        }
        jvmMain {//jvm代码目录
            dependencies {
                implementation kotlin('stdlib-jdk8')
            }
        }
        jvmTest {
            dependencies {
                implementation kotlin('test')
                implementation kotlin('test-junit')
            }
        }
        jsMain {
            dependencies {
                implementation kotlin('stdlib-js')
            }
        }
        jsTest {
            dependencies {
                implementation kotlin('test-js')
            }
        }
        macosMain {
        }
        macosTest {
        }
    }
}

根据需求修改后的文件

buildscript {//对构建脚本的配置
    repositories {//仓库配置
        mavenLocal()//使用本地maven仓库
        mavenCentral()
        maven {//kotlinx需要的仓库
            url 'https://dl.bintray.com/kotlin/kotlinx/'
        }
        maven {//阿里国内镜像仓库
            url 'http://maven.aliyun.com/nexus/content/groups/public/'
        }
        maven {
            url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'
        }
        maven { url 'https://plugins.gradle.org/m2/' }
        maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
        jcenter()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
    }
}
plugins {
    id 'org.jetbrains.kotlin.multiplatform' version '1.3.61'//配置kotlin多平台插件和版本
}
apply plugin: 'kotlinx-serialization'//引用跨平台序列化插件

repositories {//项目依赖使用的仓库
    mavenLocal()
    mavenCentral()
    maven {//配置私有maven仓库
        url QT_RELEASE_URL
        credentials {//配置私有maven仓库用户名密码
            username QT_NAME
            password QT_PASSWORD
        }
        content {//配置该maven仓库仅在查询其group符合"im.qingtui.*"的模块时使用
            // this repository *only* contains artifacts with group "my.company"
            includeGroupByRegex "im\\.qingtui.*"
        }
        mavenContent {//配置该maven仓库仅在查询release模块时使用
            releasesOnly()
        }
    }

    maven {
        url QT_SNAPSHOT_URL
        credentials {
            username QT_NAME
            password QT_PASSWORD
        }
        content {
            // this repository *only* contains artifacts with group "my.company"
            includeGroupByRegex "im\\.qingtui.*"
        }
        mavenContent {//配置该maven仓库仅在查询snapshot模块时使用
            snapshotsOnly()
        }
    }
    maven {
        url 'https://dl.bintray.com/kotlin/kotlinx/'
    }
}
group 'im.qingtui.sns'
version '0.0.1-SNAPSHOT'

kotlin {
    jvm()
    js {
        browser {
        }
        nodejs {
        }
    }
    iosArm64("ios") {//构建iOS库
        binaries {
            framework()
        }
    }
    sourceSets {
        commonMain {...}
        commonTest {...}
        jvmMain {...}
        jvmTest {...}
        jsMain {...}
        jsTest {...}
        iosMain {...}
    }
}


apply plugin: 'maven-publish'//引用maven上传插件,如果仅打包到本地,可以不使用
publishing {//配置maven上传时使用的信息
    publications {
        maven(MavenPublication) {
            //指定group/artifact/version信息,可以不填。默认使用项目group/name/version作为groupId/artifactId/version
            groupId project.group
            artifactId project.name
            version project.version
        }
    }
    repositories {
        maven {
            def VERSION = project.version.toString()
            //指定要上传的maven私服仓库地址
            url = VERSION.contains("SNAPSHOT") ? QT_SNAPSHOT_URL : QT_RELEASE_URL
            //认证用户和密码
            credentials {
                username QT_NAME
                password QT_PASSWORD
            }
        }
    }
}

提示:

Kotlin版本、Gradle版本、Xcode版本、系统版本都存在依赖关系,

所依赖的第三方库也存在依赖关系

建议均使用最新版本

可以通过maven仓库搜索查看最新版本

四、打包发布

(一)执行打包任务

打开右侧gradle面板

执行assemble任务

image

然后在项目目录下可以看到build目录

image

(二)本地依赖包

在build目录我们可以找到各个平台需要的库文件

image

在bin目录下可以找到iOS平台需要的framework文件。js目录下是js平台可以使用module。jvm以及Android平台可以直接使用libs目录下的xxx-jvm-version.jar文件

(三)上传maven仓库

我们也可以使用maven-publish插件将库上传到maven仓库中。构建脚本会分个平台生成多个平台的jar包,然后上传至maven。

apply plugin: 'maven-publish'

image

在build.gralde文件中引用maven-publish插件,并配置后,在右侧gradle的面板中即可看到对应的publish任务

image

1.本地maven仓库上传

执行publishToMavenLocal任务即可将各平台库打包成jar并发布到本地的maven仓库中。我们也可以选择性的发布某一个平台的jar到本地maven仓库中。

2.远程maven上传

执行publish任务即可将各平台库打包并发布到本地的maven仓库中。

image

(三)npm仓库上传

对于npm仓库的上传,可直接修改build/js目录下pacakage.json的相关配置,然后执行npm publish命令进行上传

五、库的使用

kotlin跨平台技术实际上已经为我们生成了各平台对应的库,在库的使用上与以往没有什么差别。Android和jvm平台可以使用本地或maven仓库中jvm平台的jar包iOS平台可以使用build目录下生成的framework库文件js平台可以将build/js目录作为module使用,或将module上传至npm

下一章我们将继续介绍在多个平台能同时使用的网络库、序列化库,使网络请求相关的代码只需要一份,即可在多个平台运行。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值