当前位置:   article > 正文

Kotlin跨平台开发(一)_kotlin actual

kotlin actual

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 {
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

根据需求修改后的文件

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
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114

提示:

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

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

    声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/959151
    推荐阅读
    相关标签
      

    闽ICP备14008679号