Getting started with Kotlin cross-platform development, just read this article~

foreword

In recent years, whether it is the original RN or the current Flutter and Compose, they are all doing one thing - cross-platform.

Their achievements are mainly cross-platform on the UI. Of course, although Flutter can handle some common business logic, it still needs to be handled separately in the case of heavy business.  

But KMM is the opposite, let us find out together~

What is KMM

KMM or Kotlin Multiplatform Mobile is an SDK designed to simplify the development of cross-platform mobile applications. With KMM developers can share common code between iOS and Android apps and write platform-specific code only when necessary. 

The official description above has said so much. Simply put, KMM focuses on cross-platform business logic, which is completely opposite to Flutter and Compose. Even so, in this era when everyone wants to cross others, KMM also said that he did not say that he would not be able to do cross-platform UI...

HelloWorld by KMM

Environment configuration

It is assumed here that you already have a Mac and installed a higher version of AndroidStudio (the configuration of Xcode will not be introduced here),

Search for the plugin Kotlin Multiplatform Mobile in AndroidStudio and install it, as shown in the figure below.

Since KMM is not particularly mature, it is recommended that developers upgrade the Kotlin plugin to the latest version to avoid some compatibility issues.

create project 

After installing the plugin and restarting, we can create a Kotlin Multiplatform App, as shown in the figure below.

Enter the project name and select the corresponding configuration

In the iOS framework distribution list, select the general framework option (for simple demonstration here, the actual project can be selected according to the needs). Click Finish to create a KMM project.

project structure

The created KMM project structure is shown in the figure below.

androidApp and iOSApp are the corresponding Android and iOS code bases. Here we mainly talk about the shared shared module, which is the part that stores the common business logic of Android and iOS.

The shared module consists of three source sets: androidMain, commonMain, and iosMain. A source set is a Gradle concept for multiple files logically grouped together, where each group has its own dependencies. In Kotlin Multiplatform, different source sets in a shared module can target different platforms. As shown below.

Multi-platform library supporting multiple targets, available in common source set commonMain. Examples include Koin, Apollo, and Okio.

android and iOSMain, these are regular libraries from related ecosystems. Can be used in native iOS projects using CocoaPods or other dependency managers and in Android projects using Gradle.

run the program

After installing the KMM plug-in, you can select the iOS virtual machine in AndroidStudio. The premise must be that the iOS virtual machine has been configured in Xcode or other places, as shown in the figure.

 We only run the Android program here, and the running result is shown in the figure below.

This result comes from the Greeting file under commonMain in the shared module, and the code is shown below.

class Greeting {
    private val platform: Platform = getPlatform()

    fun greeting(): String {
        return "Hello, ${platform.name}!"
    }
}

Running on an iOS mobile phone will display the iOS version number, which is left to the readers to try for themselves. Because my computer configuration does not allow me to install Xcode...

Realize New Year's Day countdown

Then let's see how to realize the countdown function of New Year's Day, which is actually to calculate how many days are left before New Year's Day. Is it a bit familiar~

 This part is public logic, add the following configuration in the build.gradle.kts file in the shared directory

val commonMain by getting{
    dependencies {
        implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
    }
}

In the shared/src/commonMain/kotlin directory, create a new Kotlin file, the code is as follows

import kotlinx.datetime.*

fun daysUntilNewYear(): Int {
    val today = Clock.System.todayIn(TimeZone.currentSystemDefault())
    val closestNewYear = LocalDate(today.year + 1, 1, 1)
    return today.daysUntil(closestNewYear)
}

Modify the greet method of Greeting as follows

fun greeting(): String {
   return "距离元旦还有${daysUntilNewYear()}天"
}

Run the program, the result is shown in the figure below.

 The effect of running on iOS mobile phones is also the same.

Well, this example is too simple, here is a little more practical example~

Implement network request function

add dependencies

No matter what business must use the function of network request, let's see how to deal with this part of the public logic.

First of all, we will add the dependencies. There are mainly Kotlin coroutines, serialization (Ktor usage requirements), and Ktor. Ktor is a network framework that can be used for HTTP requests. If you are not familiar with it, you can check it yourself. The code is shown below.

 val commonMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")

                implementation("io.ktor:ktor-client-core:$ktorVersion")
                implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
                implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
            }
        }

At the same time, we need to add the corresponding Ktor library under the androidMain and iOSMain directories, the code is as follows.

val androidMain by getting {
        dependencies {
            implementation("io.ktor:ktor-client-android:$ktorVersion")
        }
    }
    val iosMain by creating {
        dependencies {
            implementation("io.ktor:ktor-client-darwin:$ktorVersion")
        }
    }

Here the version of ktorVersion is 2.1.2.

add interface

Here we still use the daily question interface in "wandroid": https://wanandroid.com/wenda/list/1/json

The interface and entity class used by the Paging paging library in Compose are the same, and will not be repeated here.

Create an interface address class, the code is as follows.

object Api {
    val dataApi = "https://wanandroid.com/wenda/list/1/json"
}

Create the HttpUtil class, which is used to create the HttpClient object and obtain data. The code is as follows.

class HttpUtil {
    private val httpClient = HttpClient {
        install(ContentNegotiation) {
            json(Json {
                prettyPrint = true
                isLenient = true
                ignoreUnknownKeys = true
            })
        }
    }

    /**
     * 获取数据
     */
    suspend fun getData(): String {
        val rockets: DemoReqData =
            httpClient.get(Api.dataApi).body()
        return "${rockets.data} "
    }
}

We should all be familiar with the code here, just change a network request framework. Now that the public business logic has been processed, it is only necessary to call the method on the page side and then parse the data and display it. Here we still take the Android implementation as an example.

Implement the page layer

Write Compose code under androidApp, the code is relatively simple, just click the button to request data, and display it in the text, the code is as follows.

setContent {
            MyApplicationTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background
                ) {
                    Column() {
                        val scope = rememberCoroutineScope()
                        var text by remember { mutableStateOf("正在加载") }
                        Button(onClick = {
                            scope.launch {
                                text = try {
                                    Gson().toJson(HttpUtil().getData())
                                } catch (e: Exception) {
                                    e.localizedMessage ?: "error"
                                }
                            }
                        }) {
                            Text(text = "请求数据")
                        }
                        Greeting(text)
                    }
                }
            }
        }

Here we do not parse the data, but just convert the requested data into a Json string and display it in the text. Run the program, the default display is loading, click the button to display the data of the request interface. As shown below.

In this way, we have realized the function of network request.

write at the end

Here, congratulations, you have already started the use of KMM. More usage methods need to be continuously summarized and tried in actual projects. Jetpack is currently developing the KMM version, which will be a boost to the development of KMM~

Guess you like

Origin blog.csdn.net/huangliniqng/article/details/127457631