JSON 序列化冻结 UI
JSON serialization freezes the UI
我正在为 Android 和 iOS 制作一个 Kotlin Multiplatform 项目。我的目标是在公共模块中进行网络连接和 JSON 序列化,并在目标平台中使用该数据。
但我有一个问题:它阻止了 iOS 应用程序上的 UI。下载没问题,因为它是由网络库完成的,但是当 JSON 足够大并且序列化需要一些时间时,它会冻结 UI 直到序列化完成。
这是我的步骤:
普通
使用ktor库的请求方式:
class NetworkProvider {
private val client = HttpClient()
suspend fun request(urlString: String): String {
return client.request<String>(urlString)
}
}
具有JSON序列化的请求方法:
suspend fun request(): CustomObject {
val json = networkProvider.request("API endpoint")
val object = Json.nonstrict.parse(CustomObject().serializer(), json)
return object
}
执行请求:
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
实现DownloadListener
方法:
func onCompleted(object: CustomObject) {
// Update the UI
}
并调用请求
downloader.download()
我假设它应该在主线程中异步执行而不阻塞UI。
我做错了什么?我在调用协程时尝试使用 withContext
但它没有帮助。
有没有办法在通用模块中做繁重的任务而不阻塞特定平台的UI?
网络调用完成后,Json 解析将在主线程结束。这将阻塞主线程上的所有其他内容,包括 ui。您需要将 Json 解析发送到后台线程。下面是一些与 kotlin 多平台并发的例子
JSON 解析是一项繁重的任务,需要在后台线程上完成。不是在主队列上异步调度,而是在全局队列上异步调度。
我正在为 Android 和 iOS 制作一个 Kotlin Multiplatform 项目。我的目标是在公共模块中进行网络连接和 JSON 序列化,并在目标平台中使用该数据。
但我有一个问题:它阻止了 iOS 应用程序上的 UI。下载没问题,因为它是由网络库完成的,但是当 JSON 足够大并且序列化需要一些时间时,它会冻结 UI 直到序列化完成。
这是我的步骤:
普通
使用ktor库的请求方式:
class NetworkProvider {
private val client = HttpClient()
suspend fun request(urlString: String): String {
return client.request<String>(urlString)
}
}
具有JSON序列化的请求方法:
suspend fun request(): CustomObject {
val json = networkProvider.request("API endpoint")
val object = Json.nonstrict.parse(CustomObject().serializer(), json)
return object
}
执行请求:
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
实现DownloadListener
方法:
func onCompleted(object: CustomObject) {
// Update the UI
}
并调用请求
downloader.download()
我假设它应该在主线程中异步执行而不阻塞UI。
我做错了什么?我在调用协程时尝试使用 withContext
但它没有帮助。
有没有办法在通用模块中做繁重的任务而不阻塞特定平台的UI?
网络调用完成后,Json 解析将在主线程结束。这将阻塞主线程上的所有其他内容,包括 ui。您需要将 Json 解析发送到后台线程。下面是一些与 kotlin 多平台并发的例子
JSON 解析是一项繁重的任务,需要在后台线程上完成。不是在主队列上异步调度,而是在全局队列上异步调度。