欢迎光临
我们一直在努力

Kotlin+Compose四大核心库实战指南

我来详细讲解这四个在 Kotlin + Compose 生态中常用的核心库,并展示它们如何协同工作构建现代化应用架构。


  • Ktor – Kotlin 多平台网络库 Ktor 是 JetBrains 官方推出的异步网络框架,采用 Kotlin Coroutines 原生实现,支持 Android、iOS、后端等多平台共享网络代码。 核心特性
    • 多引擎支持:OkHttp(Android)、CIO(Kotlin纯协程)、Darwin(iOS)
    • 类型安全:配合 Kotlin Serialization 实现自动 JSON 解析
    • 插件体系:日志、重试、缓存、身份验证等通过插件配置 依赖配置

    // build.gradle.kts (Module level)
    dependencies {
    // Ktor 客户端核心
    implementation("io.ktor:ktor-client-android:2.3.7")

    // 内容协商与序列化 (必须)
    implementation("io.ktor:ktor-client-content-negotiation:2.3.7")
    implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.7")

    // 日志插件 (开发调试)
    implementation("io.ktor:ktor-client-logging:2.3.7")

    // 引擎可选:OkHttp (推荐用于Android,支持HTTP/2)
    implementation("io.ktor:ktor-client-okhttp:2.3.7")
    }

    实战:封装 Repository 层

    // 1. 定义数据模型
    @Serializable
    data class User(
    val id: Int,
    val name: String,
    val email: String
    )

    // 2. 配置 HttpClient (依赖注入时提供)
    object HttpClientProvider {
    fun create(): HttpClient = HttpClient(OkHttp) {
    // 配置JSON自动序列化
    install(ContentNegotiation) {
    json(Json {
    ignoreUnknownKeys = true // 忽略未知字段,防崩溃
    prettyPrint = true
    })
    }

    // 日志插件
    install(Logging) {
    logger = Logger.ANDROID
    level = LogLevel.ALL
    }

    // 默认请求配置
    defaultRequest {
    header(HttpHeaders.ContentType, ContentType.Application.Json)
    url("https://api.example.com/")
    }
    }
    }

    // 3. Repository 层
    class UserRepository(private val client: HttpClient) {
    suspend fun getUsers(): List<User> =
    client.get("users").body()

    suspend fun createUser(user: User): User =
    client.post("users") {
    setBody(user)
    }.body()

    // 流式响应 (下载大文件或SSE)
    suspend fun downloadFile(): Flow<ByteReadChannel> = flow {
    client.prepareGet("large-file.zip").execute { response ->
    emit(response.bodyAsChannel())
    }
    }
    }


  • Koin – pragmatic 轻量级依赖注入 Koin 是专为 Kotlin 设计的依赖注入框架,相比 Hilt/Dagger 无代码生成、编译更快、配置更简洁,且完美支持 Kotlin Multiplatform 和 Compose。 核心概念对比 (Koin vs Hilt) 特性 Koin Hilt 配置方式 Kotlin DSL 注解处理器 (KAPT/KSP) 编译速度 快 (无代码生成) 较慢 多平台支持 ✅ KMP ❌ Android only 学习曲线 低 较高 与Compose集成 koinCompose 模块 hilt-navigation-compose 依赖配置
  • dependencies {
    // Koin BOM 管理版本
    implementation(platform("io.insert-koin:koin-bom:3.5.3"))

    // 核心
    implementation("io.insert-koin:koin-core")
    implementation("io.insert-koin:koin-android")

    // Compose 专用扩展 (关键)
    implementation("io.insert-koin:koin-androidx-compose:3.5.3")

    // 如果需要 ViewModel 注入支持
    implementation("io.insert-koin:koin-androidx-viewmodel")
    }

    实战:模块定义与注入

    // 1. 定义 Module (替代 Dagger 的 Module+Component)
    val appModule = module {
    // 单例模式 (应用生命周期)
    single { HttpClientProvider.create() }

    // 工厂模式 (每次创建新实例)
    factory { UserRepository(get()) }

    // ViewModel 注入 (配合 koin-androidx-viewmodel)
    viewModel { UserViewModel(get()) }

    // 带参数的 ViewModel
    viewModel { params -> DetailViewModel(params.get(), get()) }
    }

    // 2. Application 中启动 Koin
    class MyApplication : Application() {
    override fun onCreate() {
    super.onCreate()
    startKoin {
    androidContext(this@MyApplication)
    androidLogger(Level.DEBUG)
    modules(appModule, networkModule, databaseModule)
    }
    }
    }

    // 3. 在 Compose 中使用
    @Composable
    fun UserScreen() {
    // 直接获取 ViewModel (自动绑定生命周期)
    val viewModel: UserViewModel = koinViewModel()

    // 或者直接注入 Repository (不推荐在UI层直接使用)
    val repo: UserRepository = get()

    val users by viewModel.users.collectAsState()

    LazyColumn {
    items(users) { user ->
    UserItem(user)
    }
    }
    }

    // 4. 带参数的 ViewModel 使用
    @Composable
    fun DetailScreen(userId: Int) {
    val viewModel: DetailViewModel = koinViewModel(
    parameters = { parametersOf(userId) }
    )
    }


  • Voyager – Compose 专属导航库 Voyager 是专为 Jetpack Compose 设计的导航库,相比官方 Navigation Compose 提供了 类型安全导航、多平台支持、更灵活的转场动画 和更简洁的 API。 核心优势
    • 类型安全:无需字符串路由,使用密封类/Screen 对象
    • 状态管理:每个 Screen 拥有独立的 ViewModel 作用域
    • 多平台:支持 Android、Desktop、iOS (通过 Compose Multiplatform)
    • 丰富组件:BottomSheet、TabNavigator、Navigator 嵌套 依赖配置

    dependencies {
    val voyagerVersion = "1.0.0"

    // 核心导航
    implementation("cafe.adriel.voyager:voyager-navigator:$voyagerVersion")

    // ViewModel 支持 (与 Koin/Hilt 集成)
    implementation("cafe.adriel.voyager:voyager-koin:$voyagerVersion")

    // Tab 导航 (底部导航栏)
    implementation("cafe.adriel.voyager:voyager-tab-navigator:$voyagerVersion")

    // BottomSheet 支持
    implementation("cafe.adriel.voyager:voyager-bottom-sheet-navigator:$voyagerVersion")

    // 转场动画
    implementation("cafe.adriel.voyager:voyager-transitions:$voyagerVersion")
    }

    实战:类型安全导航架构

    // 1. 定义 Screen (密封类实现 Screen 接口)
    sealed class AppScreen : Screen {
    data object Home : AppScreen() {
    @Composable
    override fun Content() {
    val navigator = LocalNavigator.currentOrThrow
    HomeScreen(
    onNavigateToDetail = { userId ->
    navigator.push(Detail(userId))
    }
    )
    }
    }

    data class Detail(val userId: Int) : AppScreen() {
    @Composable
    override fun Content() {
    // 自动管理 ViewModel 生命周期,与 Koin 集成
    val viewModel: DetailViewModel = getScreenModel()

    DetailScreen(viewModel = viewModel)
    }
    }
    }

    // 2. 根布局设置 (Activity 中)
    setContent {
    MaterialTheme {
    // 支持 BottomSheet 的 Navigator
    BottomSheetNavigator {
    Navigator(AppScreen.Home) { navigator ->
    // 全局转场动画
    SlideTransition(navigator)
    }
    }
    }
    }

    // 3. Tab 导航实现 (底部导航栏)
    object HomeTab : Tab {
    override val options: TabOptions
    @Composable
    get() = TabOptions(
    index = 0u,
    title = "Home",
    icon = rememberVectorPainter(Icons.Default.Home)
    )

    @Composable
    override fun Content() {
    val tabNavigator = LocalTabNavigator.current

    Column {
    // 内容区域
    Navigator(HomeScreen)

    // 底部导航
    NavigationBar {
    TabNavigationItem(HomeTab)
    TabNavigationItem(ProfileTab)
    }
    }
    }
    }

    @Composable
    private fun RowScope.TabNavigationItem(tab: Tab) {
    val tabNavigator = LocalTabNavigator.current

    NavigationBarItem(
    selected = tabNavigator.current == tab,
    onClick = { tabNavigator.current = tab },
    icon = { Icon(painter = tab.options.icon!!, contentDescription = tab.options.title) },
    label = { Text(tab.options.title) }
    )
    }

    // 4. 返回处理与生命周期
    @Composable
    fun DetailScreen() {
    val navigator = LocalNavigator.currentOrThrow

    // 监听返回键
    BackHandler {
    navigator.pop()
    }

    // 替代 onCleared() 清理资源
    DisposableEffect(Unit) {
    onDispose {
    // 清理操作
    }
    }
    }


  • MVVM 架构实践 (ViewModel + StateFlow) 在 Compose 中,虽然没有专门的"MVVM库",但通过 Jetpack ViewModel + StateFlow/Compose State 结合 Koin 注入,构成了标准的 MVVM 实现层。 完整架构示例
  • // 1. ViewModel 层 (与 Koin 集成)
    class UserViewModel(
    private val repository: UserRepository
    ) : ViewModel() {

    // UI State 密封类 (替代多个 LiveData)
    sealed class UiState {
    data object Loading : UiState()
    data class Success(val users: List<User>) : UiState()
    data class Error(val message: String) : UiState()
    }

    private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
    val uiState: StateFlow<UiState> = _uiState.asStateFlow()

    init {
    loadUsers()
    }

    private fun loadUsers() {
    viewModelScope.launch {
    _uiState.value = UiState.Loading
    try {
    val users = repository.getUsers()
    _uiState.value = UiState.Success(users)
    } catch (e: Exception) {
    _uiState.value = UiState.Error(e.message ?: "Unknown error")
    }
    }
    }

    // 事件处理 (单向数据流)
    fun onUserClick(user: User) {
    // 处理业务逻辑
    }
    }

    // 2. UI 层 (Compose)
    @Composable
    fun UserListScreen(
    viewModel: UserViewModel = koinViewModel(),
    onNavigateToDetail: (Int) -> Unit
    ) {
    val state by viewModel.uiState.collectAsStateWithLifecycle()

    when (val currentState = state) {
    is UserViewModel.UiState.Loading -> {
    Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
    CircularProgressIndicator()
    }
    }
    is UserViewModel.UiState.Success -> {
    LazyColumn {
    items(currentState.users) { user ->
    UserItem(
    user = user,
    onClick = { viewModel.onUserClick(user) }
    )
    }
    }
    }
    is UserViewModel.UiState.Error -> {
    ErrorMessage(
    message = currentState.message,
    onRetry = { viewModel.loadUsers() }
    )
    }
    }
    }

    // 3. Koin 模块配置
    val viewModelModule = module {
    viewModel { UserViewModel(get()) }
    viewModel { (userId: Int) -> DetailViewModel(userId, get()) }
    }


    完整集成:四库协同实战 下面展示一个典型页面的完整代码,集成 Ktor(网络) + Koin(DI) + Voyager(路由) + ViewModel(MVVM):

    // 数据层
    class NewsRepository(private val client: HttpClient) {
    suspend fun fetchNews(): List<News> = client.get("news").body()
    }

    // ViewModel 层
    class NewsViewModel(private val repo: NewsRepository) : ViewModel() {
    var news by mutableStateOf<List<News>>(emptyList())
    private set

    fun load() = viewModelScope.launch {
    news = repo.fetchNews()
    }
    }

    // Screen 层 (Voyager)
    class NewsScreen : Screen {
    @Composable
    override fun Content() {
    // Koin 注入 ViewModel
    val viewModel: NewsViewModel = getScreenModel()
    val navigator = LocalNavigator.currentOrThrow

    LaunchedEffect(Unit) { viewModel.load() }

    Scaffold(
    topBar = { TopAppBar(title = { Text("News") }) }
    ) { padding ->
    LazyColumn(modifier = Modifier.padding(padding)) {
    items(viewModel.news) { item ->
    ListItem(
    headlineContent = { Text(item.title) },
    modifier = Modifier.clickable {
    // 类型安全导航
    navigator.push(NewsDetailScreen(item.id))
    }
    )
    }
    }
    }
    }
    }

    // Application 初始化
    class MyApp : Application() {
    override fun onCreate() {
    super.onCreate()
    startKoin {
    androidContext(this@MyApp)
    modules(module {
    single { HttpClientProvider.create() }
    single { NewsRepository(get()) }
    viewModel { NewsViewModel(get()) }
    })
    }
    }
    }

    选型建议 场景 推荐选择 理由 纯 Android 项目 Hilt + Navigation Compose 官方支持,社区资源多 KMP 多平台项目 Koin + Ktor + Voyager 代码可在 iOS/Desktop 复用 快速原型开发 Koin + Voyager 配置简单,编译快,类型安全 复杂导航需求 Voyager 支持嵌套导航、共享元素转场、BottomSheet 这套组合拳(Koin + Ktor + Voyager)构成了 Kotlin Multiplatform Mobile (KMM) 生态中最现代化的技术栈,可实现业务逻辑与 UI 代码在 Android/iOS 间的高复用率。

    赞(0)
    未经允许不得转载:171主机测评 » Kotlin+Compose四大核心库实战指南
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址