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)
}
}
}
Dispatcher とコルーチンのスコープ:
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 をブロックすることなく、共通モジュールで重いタスクを実行する方法はありますか?