KMP Common - 项目架构

一、概念

二、模块依赖关系

shared 模块用于存放各平台通用的界面和业务能力,desktopApp 模块里用 Window 宿主把它装起来,androidApp 模块里用 Activity 宿主把它装起来,各平台的壳不一样。

共享层(shared模块)表达通用的界面状态和业务逻辑。
平台层(androidApp、iosApp、desktopApp等模块)处理不同平台的配置差异。

shared/App.kt

@Composable
fun App() {
    Text("Hello Word!")
}

androidApp/MainActivity.kt

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        enableEdgeToEdge()
        super.onCreate(savedInstanceState)
        setContent {
            App()
        }
    }
}

desktopApp/main.kt

fun main() = application {
    Window(
        onCloseRequest = ::exitApplication,
        title = "TinyBeautyKMP",
    ) {
        App()
    }
}

三、shared 模块

3.1 分包

小而稳定的平台差异,可以使用 expect / actual。复杂一点的平台能力,更适合用接口

共享包(commonMain包)

存放所有目标平台通用的代码:通用 UI、页面状态模型、普通 Kotlin 数据类、不依赖平台 API 的业务、平台能力的接口定义(except)。

平台包(androidMain、iosMain、jvmMain等包)

同一个功能在不同平台实现起来不同,将平台能力交由 commonMain 调用(actual)。
// commonMain
expect fun platformName(): String
// androidMain
actual fun platformName(): String = "Android"
// desktopMain
actual fun platformName(): String = "Desktop"

commonMain 只依赖 FilePicker,desktopMain 和 androidMain 分别提供实现。这样写的好处是,页面逻辑依然能共享,平台差异也不会泄漏到 UI 深处。

// commonMain
interface FilePicker {
    suspend fun pickFile(): String?
}
FilePicker.pickFile()
// androidMain
object FilePicker : FilePicker {...}

3.2 build.gradle.kts

plugins {
    // KMP插件
    alias(libs.plugins.kotlinMultiplatform)
    // Android 构建
    alias(libs.plugins.androidMultiplatformLibrary)
    // CMP 插件和编译器
    alias(libs.plugins.composeMultiplatform)
    alias(libs.plugins.composeCompiler)
}

kotlin {
    // 编译出 iOS 代码
    listOf(
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "Shared"
            isStatic = true
        }
    }
    // 编译出 Desktop 代码
    jvm()
    // 编译出 Android 代码
    androidLibrary {
       namespace = "com.hugmua.tinybeautykmp.shared"
       compileSdk = libs.versions.android.compileSdk.get().toInt()
       minSdk = libs.versions.android.minSdk.get().toInt()
    
       compilerOptions {
           jvmTarget = JvmTarget.JVM_11
       }
       androidResources {
           enable = true
       }
       withHostTest {
           isIncludeAndroidResources = true
       }
    }
    // 为不同平台添加依赖
    sourceSets {
        androidMain.dependencies {
            implementation(libs.compose.uiToolingPreview)
        }
        commonMain.dependencies {
            implementation(libs.compose.runtime)
            implementation(libs.compose.foundation)
            implementation(libs.compose.material3)
            implementation(libs.compose.ui)
            implementation(libs.compose.components.resources)
            implementation(libs.compose.uiToolingPreview)
            implementation(libs.androidx.lifecycle.viewmodelCompose)
            implementation(libs.androidx.lifecycle.runtimeCompose)
        }
        commonTest.dependencies {
            implementation(libs.kotlin.test)
        }
    }
}

dependencies {
    androidRuntimeClasspath(libs.compose.uiTooling)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值