如何在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
相关产品推荐
相关产品推荐

