Jetpack Compose-文件下载

前言

本文主要是文件的同步下载,结合flow实现线程的切换。

下载工具类

下载文件到临时目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import android.content.Context
import java.io.File
import java.io.FileOutputStream
import java.net.HttpURLConnection
import java.net.URL

object ZFileDownloadUtils {
fun downloadFileToTempFolder(
context: Context,
fileUrl: String,
suffix: String = ".jpg"
): String? {
var filePath: String? = null
var mSuffix = suffix
try {
// 创建 URL 对象
val url = URL(fileUrl)
// 打开连接
val connection = url.openConnection() as HttpURLConnection
// 设置请求方法
connection.requestMethod = "GET"

if (fileUrl.contains(".")) {
mSuffix = fileUrl.substring(fileUrl.lastIndexOf("."))
}

// 获取响应码
val responseCode = connection.responseCode
if (responseCode == HttpURLConnection.HTTP_OK) {
// 获取输入流
val inputStream = connection.inputStream

// 创建临时文件
val tempFile = File.createTempFile("downloaded_file", mSuffix, context.cacheDir)
filePath = tempFile.absolutePath

// 创建文件输出流
val outputStream = FileOutputStream(tempFile)

// 缓冲区大小
val buffer = ByteArray(4096)
var bytesRead: Int
// 从输入流读取数据并写入输出流
while (inputStream.read(buffer).also { bytesRead = it } != -1) {
outputStream.write(buffer, 0, bytesRead)
}

// 关闭流
outputStream.close()
inputStream.close()
}
// 断开连接
connection.disconnect()
} catch (e: Exception) {
e.printStackTrace()
}
return filePath
}
}

调用

viewModel中

1
2
3
4
5
6
7
8
9
10
11
12
13
fun downloadFile(context: Context, fileUrl: String) {
viewModelScope.launch {
flow {
val filePath = ZFileDownloadUtils.downloadFileToTempFolder(context, fileUrl)
emit(filePath)
}
.flowOn(Dispatchers.IO)
.collect {
result ->
Log.i(TAG, "downloadFile: $result")
}
}
}

Compose中

1
2
3
4
val context = LocalContext.current
LaunchedEffect(Unit) {
vm.downloadFile(context, CommonData.fileShowUrl + vm.imgUrl.value)
}