You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin Multiplatform中使用Okio下载网络图片?

在Kotlin Multiplatform中使用Okio下载图片

首先确保你的项目已引入Okio依赖,在build.gradle.kts的commonMain依赖块中添加:

implementation("com.squareup.okio:okio:3.6.0")

步骤1:定义平台特定的保存目录

由于不同平台的文件存储规则不同,先通过expect/actual机制获取壁纸保存路径:

commonMain代码

expect fun getWallpaperSaveDirectory(): String

Android平台(androidMain)

actual fun getWallpaperSaveDirectory(): String {
    // 示例:获取应用私有图片目录,可根据需求调整
    val context = ApplicationProvider.getApplicationContext<Context>()
    return context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)?.absolutePath ?: ""
}

iOS平台(iosMain)

actual fun getWallpaperSaveDirectory(): String {
    // 示例:获取应用文档目录下的Wallpapers子目录
    val documentsDir = NSFileManager.defaultManager.URLForDirectory(
        NSDocumentDirectory,
        NSUserDomainMask,
        null,
        true,
        null
    )?.path ?: ""
    return "$documentsDir/Wallpapers"
}

步骤2:实现Okio下载逻辑

修改你的downloadWallpaper函数,加入下载逻辑,包含网络流读取、文件写入和错误处理:

import okio.FileSystem
import okio.Path.Companion.toPath
import okio.buffer
import okio.source
import java.net.HttpURLConnection

fun downloadWallpaper(
    wallpaperId: String
) {
    getWallpaperDownloadUrl(wallpaperId) { wallpaperUrl ->
        // 后台执行下载操作,避免阻塞主线程
        kotlinx.coroutines.GlobalScope.launch {
            runCatching {
                val saveDir = getWallpaperSaveDirectory()
                val savePath = "$saveDir/wallpaper_$wallpaperId.jpg".toPath()
                
                // 创建父目录(如果不存在)
                FileSystem.SYSTEM.createDirectories(savePath.parent!!, mustCreate = false)
                
                // 建立网络连接并获取Okio Source
                val connection = java.net.URL(wallpaperUrl).openConnection() as HttpURLConnection
                connection.requestMethod = "GET"
                connection.doInput = true
                connection.connect()
                
                // 读取网络流并写入文件
                connection.inputStream.source().buffer().use { input ->
                    FileSystem.SYSTEM.sink(savePath).buffer().use { output ->
                        output.writeAll(input)
                    }
                }
                
                // 下载成功提示
                addMessage(InfoUiMessage(message = Res.string.wallpaper_downloaded))
            }.onFailure { e ->
                // 处理下载失败场景
                addMessage(InfoUiMessage(message = Res.string.wallpaper_download_failed))
                e.printStackTrace()
            }
        }
    }
}

关键注意事项

  • 线程安全:下载操作必须在后台线程执行,示例中使用GlobalScope,实际项目建议使用自定义CoroutineScope以避免内存泄漏。
  • 权限配置:Android平台需根据系统版本配置文件访问权限(如Scoped Storage),iOS需在Info.plist中添加文件访问相关权限描述。
  • 网络库适配:如果项目已集成Ktor Client,可替换HttpURLConnection为Ktor的响应流读取,示例如下:
    val response = ktorClient.get(wallpaperUrl)
    response.bodyAsChannel().source().buffer().use { input ->
        FileSystem.SYSTEM.sink(savePath).buffer().use { output ->
            output.writeAll(input)
        }
    }
    
  • 文件格式适配:示例中默认使用.jpg后缀,可根据实际图片类型动态调整。

内容的提问来源于stack exchange,提问作者the great warrior

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 05:25:00