我正在为 Android 和 iOS 制作一个 Kotlin 多平台项目。我的目标是在公共模块中进行网络和 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?