协程 运行 在主线程而不是后台
Coroutines running on the main thread instead of background
我有一个应用程序,用户在其中从文件资源管理器中选择一个 pdf,然后我需要将该 pdf 转换为 base 64。
以下是我将 pdf 转换为 base64 的代码
private fun convertImageFileToBase64(imageFile: File?): String {
return FileInputStream(imageFile).use { inputStream ->
ByteArrayOutputStream().use { outputStream ->
Base64OutputStream(outputStream, Base64.DEFAULT).use { base64FilterStream ->
inputStream.copyTo(base64FilterStream)
base64FilterStream.flush()
outputStream.toString()
}
}
}
}
所以在我获取 pdf 文件的 onActivityResult
中,我正在编写以下代码
launch {
withContext(Dispatchers.IO) {
generatedBase64 = convertImageFileToBase64(file)
}
//upload generatedBase64 to server
}
但是代码在主线程而不是后台线程上运行,如果 pdf 文件很大,我的 ui 会冻结一段时间。我也尝试了 AsyncTask 并尝试在 doInBackground
方法中执行转换,但我面临同样的问题
如果您使用 Dispatchers.Main + Job()
之类的内容作为启动协程的上下文,那么在您有注释 "upload generatedBase64 to server" 的地方,它将 运行 在主线程上。您需要像调用 convertImageFileToBase64
函数一样切换上下文以将 generatedBase64
上传到服务器,即使用 withContext(Dispatchers.IO)
:
launch {
withContext(Dispatchers.IO) {
generatedBase64 = convertImageFileToBase64(file)
//upload generatedBase64 to server here
}
// do UI stuff here, e.g. show some message, set text to TextView etc.
}
我有一个应用程序,用户在其中从文件资源管理器中选择一个 pdf,然后我需要将该 pdf 转换为 base 64。
以下是我将 pdf 转换为 base64 的代码
private fun convertImageFileToBase64(imageFile: File?): String {
return FileInputStream(imageFile).use { inputStream ->
ByteArrayOutputStream().use { outputStream ->
Base64OutputStream(outputStream, Base64.DEFAULT).use { base64FilterStream ->
inputStream.copyTo(base64FilterStream)
base64FilterStream.flush()
outputStream.toString()
}
}
}
}
所以在我获取 pdf 文件的 onActivityResult
中,我正在编写以下代码
launch {
withContext(Dispatchers.IO) {
generatedBase64 = convertImageFileToBase64(file)
}
//upload generatedBase64 to server
}
但是代码在主线程而不是后台线程上运行,如果 pdf 文件很大,我的 ui 会冻结一段时间。我也尝试了 AsyncTask 并尝试在 doInBackground
方法中执行转换,但我面临同样的问题
如果您使用 Dispatchers.Main + Job()
之类的内容作为启动协程的上下文,那么在您有注释 "upload generatedBase64 to server" 的地方,它将 运行 在主线程上。您需要像调用 convertImageFileToBase64
函数一样切换上下文以将 generatedBase64
上传到服务器,即使用 withContext(Dispatchers.IO)
:
launch {
withContext(Dispatchers.IO) {
generatedBase64 = convertImageFileToBase64(file)
//upload generatedBase64 to server here
}
// do UI stuff here, e.g. show some message, set text to TextView etc.
}