Ios JSON序列化会冻结UI
我正在为Android和iOS制作一个Kotlin多平台项目。我的目标是在公共模块中进行联网和JSON序列化,并在目标平台中使用这些数据 但我有一个问题:它会阻塞iOS应用程序上的UI。下载是可以的,因为它是由网络库完成的,但是当JSON足够大并且序列化需要一些时间时,它会冻结UI直到序列化完成 以下是我的步骤: 普通 使用ktor库的请求方法:Ios JSON序列化会冻结UI,ios,swift,kotlin,kotlin-coroutines,kotlin-multiplatform,Ios,Swift,Kotlin,Kotlin Coroutines,Kotlin Multiplatform,我正在为Android和iOS制作一个Kotlin多平台项目。我的目标是在公共模块中进行联网和JSON序列化,并在目标平台中使用这些数据 但我有一个问题:它会阻塞iOS应用程序上的UI。下载是可以的,因为它是由网络库完成的,但是当JSON足够大并且序列化需要一些时间时,它会冻结UI直到序列化完成 以下是我的步骤: 普通 使用ktor库的请求方法: class NetworkProvider { private val client = HttpClient() suspend f
class NetworkProvider {
private val client = HttpClient()
suspend fun request(urlString: String): String {
return client.request<String>(urlString)
}
}
执行请求:
class Downloader {
var listener: DownloadListener? = null
fun download() {
CustomCoroutineScope().launch {
val object = request()
listener?.onCompleted(object)
}
}
}
调度程序和协同路由范围:
class UIDispatcher : CoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
dispatch_async(dispatch_get_main_queue()) {
block.run()
}
}
}
internal class CustomCoroutineScope : CoroutineScope {
private val dispatcher = UIDispatcher()
private val job = Job()
override val coroutineContext: CoroutineContext
get() = dispatcher + job
}
iOS
实施下载侦听器方法:
func onCompleted(object: CustomObject) {
// Update the UI
}
然后打电话请求
downloader.download()
我假设它应该在主线程中异步执行,而不会阻塞UI
我做错了什么?在调用协同程序时,我尝试使用和context
,但没有任何帮助
有没有办法在公共模块中完成繁重的任务而不阻塞特定平台中的UI?一旦网络调用完成,Json解析将在主线程上结束。这将阻止主线程上的所有其他内容,包括ui。您需要将Json解析发送到后台线程。下面是一些与kotlin多平台并发的示例
JSON解析是一项繁重的任务,需要在后台线程上完成。不要在主队列上异步调度,而是在全局队列上异步调度。不要运行此同步。如果需要很长时间,请将其从主线程上移开。使它异步只意味着它不会立即阻塞。嘿@KevinGalligan,我对你的代码有点小麻烦。我的应用程序流与krlb的应用程序流几乎相同,并且您的后台任务解决方案对于解析非常有用。然而,当我经历调用解析周期时,我的HttpClient被冻结,无法再使用,我必须创建另一个,这不是一个可接受的解决方案。经过一番挖掘,我得出了一个结论,这一切都发生了,因为协程延续被传递到后台任务
,这冻结了协程中的几乎所有内容。你知道如何解决这个问题吗?@JanStoltman协同程序和延续不应该被冻结。它们被保存在主线程中。我看不到您的代码,但我假设您是在后台lambda中捕获HttpClient。小结,如果您有一些示例代码要查看,我可以说得更好。@KevinGalligan您可以在这里找到我代码的重要部分:我使用与Droidcon相同的后台任务。据我所知,我们将继续传递给包装在lambda中的JobWrapper。冻结这个工作包装不会冻结整个续集吗?你知道我的问题吗?
downloader.download()