Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
完全に理解した気になる Kotlin Coroutines
Search
takahirom
July 03, 2018
Programming
2.9k
8
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
完全に理解した気になる Kotlin Coroutines
takahirom
July 03, 2018
More Decks by takahirom
See All by takahirom
AndroidアプリのAI実装をAndroidifyで学ぶ ー Google公式サンプルによる体験と実装 ー
takahirom
0
140
AIエージェントによるテストフレームワーク Arbigent
takahirom
0
1k
Google の LLM ライブラリ を Android アプリで 使うには?
takahirom
1
2.1k
Robolectric Native Graphics and Roborazzi
takahirom
1
2.3k
Androidアプリで安定して動作させ継続的に開発するために設計の原則を利用して開発した話
takahirom
3
1.4k
Android Tools & Performance
takahirom
1
1.2k
Jetpack Compose State Practices
takahirom
1
1.5k
Inside Jetpack Compose
takahirom
1
1.1k
What’s new in Android Jetpack and Tools
takahirom
0
430
Other Decks in Programming
See All in Programming
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
190
C# and C++ Interoperability - cho-dotnetnew
harukasao
0
260
Dataformのリポジトリを立ち上げるときにまずやること / dataform-day0-2026
snhryt
0
170
ユニットテストの先へ:テスト技法で要求・仕様を整理するJava開発実践 / Beyond_Unit_Testing_Practical_Java_Development_Techniques_for_Organizing_Requirements_and_Specifications
shimashima35
0
410
Contextとはなにか
chiroruxx
1
330
その問い、本当に正しいですか?AI時代のエンジニアに必要な哲学と認知科学 / ai-philosophy-cognitive-science
minodriven
11
5.8k
IBM Bobを活用したレガシーアプリの最新化
oniak3ibm
PRO
1
200
LLM本来の能力を解き放つサンドボックス技術とAI民主化への適用
yukukotani
3
4.3k
Even G2とAWSで推しのエージェントを召喚しよう!
har1101
1
120
ADKを使って簡単にAIエージェントを作ってみよう
k1mu21
0
270
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.3k
そのテスト、説明できますか?~LWテスト戦略FW~のご紹介
nakahara
0
150
Featured
See All Featured
Unsuck your backbone
ammeep
672
58k
The Curse of the Amulet
leimatthew05
1
13k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
340
Technical Leadership for Architectural Decision Making
baasie
3
420
4 Signs Your Business is Dying
shpigford
187
22k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
420
Context Engineering - Making Every Token Count
addyosmani
9
970
Music & Morning Musume
bryan
47
7.2k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5.9k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
Fireside Chat
paigeccino
42
4k
Transcript
㸣Ⰻח椚鍑׃孡חז ,PUMJO$PSPVUJOFT UBLBIJSPN
˖ UBLBIJSPN !OFX@SVOOBCMF דׅկ ˖ 劤せכ嬁「䃨峔 ׄױַמ דׅկ ˖ "OESPJEָ㥨ֹדׅ
˖ "CFNB57ך"OESPJE،فٔ⡲גְתׅկ ˖ 2JJUBח剅ְךדծ鋅זָ耀ְג ְֻׁկ ˖ IUUQTRJJUBDPNUBLBIJSPNJUFNT CBBEDDGCB 荈ⴓחאְג
$PSPVUJOFTך 椚鍑ָꨇ׃ְ
⢪$PSPVUJOFTך"1*
⢪$PSPVUJOFTך"1* ˖ MBVODI
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU ˖
$PSPVUJOF$POUFYU
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU ˖
$PSPVUJOF$POUFYU ˖ $PNNPO1PPM
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU ˖
$PSPVUJOF$POUFYU ˖ $PNNPO1PPM ˖ $POUJOVBUJPO
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU ˖
$PSPVUJOF$POUFYU ˖ $PNNPO1PPM ˖ $POUJOVBUJPO ˖ TVTQFOE$PSPVUJOF
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU ˖
$PSPVUJOF$POUFYU ˖ $PNNPO1PPM ˖ $POUJOVBUJPO ˖ TVTQFOE$PSPVUJOF ˖ $PSPVUJOF%JTQBUDIFS
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU ˖
$PSPVUJOF$POUFYU ˖ $PNNPO1PPM ˖ $POUJOVBUJPO ˖ TVTQFOE$PSPVUJOF ˖ $PSPVUJOF%JTQBUDIFS ˖ %FGFSSFE
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU ˖
$PSPVUJOF$POUFYU ˖ $PNNPO1PPM ˖ $POUJOVBUJPO ˖ TVTQFOE$PSPVUJOF ˖ $PSPVUJOF%JTQBUDIFS ˖ %FGFSSFE ˖ 6ODPOOFE
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU ˖
$PSPVUJOF$POUFYU ˖ $PNNPO1PPM ˖ $POUJOVBUJPO ˖ TVTQFOE$PSPVUJOF ˖ $PSPVUJOF%JTQBUDIFS ˖ %FGFSSFE ˖ 6ODPOOFE ˖ BOESPJE6*
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU ˖
$PSPVUJOF$POUFYU ˖ $PNNPO1PPM ˖ $POUJOVBUJPO ˖ TVTQFOE$PSPVUJOF ˖ $PSPVUJOF%JTQBUDIFS ˖ %FGFSSFE ˖ 6ODPOOFE ˖ BOESPJE6* ˖ %FGBVMU%JTQBUDIFS
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU ˖
$PSPVUJOF$POUFYU ˖ $PNNPO1PPM ˖ $POUJOVBUJPO ˖ TVTQFOE$PSPVUJOF ˖ $PSPVUJOF%JTQBUDIFS ˖ %FGFSSFE ˖ 6ODPOOFE ˖ BOESPJE6* ˖ %FGBVMU%JTQBUDIFS ˖ 3FOEF[WPVT$IBOOFM
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU ˖
$PSPVUJOF$POUFYU ˖ $PNNPO1PPM ˖ $POUJOVBUJPO ˖ TVTQFOE$PSPVUJOF ˖ $PSPVUJOF%JTQBUDIFS ˖ %FGFSSFE ˖ 6ODPOOFE ˖ BOESPJE6* ˖ %FGBVMU%JTQBUDIFS ˖ 3FOEF[WPVT$IBOOFM ˖ 4FOE$IBOOFM
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU ˖
$PSPVUJOF$POUFYU ˖ $PNNPO1PPM ˖ $POUJOVBUJPO ˖ TVTQFOE$PSPVUJOF ˖ $PSPVUJOF%JTQBUDIFS ˖ %FGFSSFE ˖ 6ODPOOFE ˖ BOESPJE6* ˖ %FGBVMU%JTQBUDIFS ˖ 3FOEF[WPVT$IBOOFM ˖ 4FOE$IBOOFM ˖ 3FDFJWF$IBOOFM
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU ˖
$PSPVUJOF$POUFYU ˖ $PNNPO1PPM ˖ $POUJOVBUJPO ˖ TVTQFOE$PSPVUJOF ˖ $PSPVUJOF%JTQBUDIFS ˖ %FGFSSFE ˖ 6ODPOOFE ˖ BOESPJE6* ˖ %FGBVMU%JTQBUDIFS ˖ 3FOEF[WPVT$IBOOFM ˖ 4FOE$IBOOFM ˖ 3FDFJWF$IBOOFM ˖ BDUPS
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU ˖
$PSPVUJOF$POUFYU ˖ $PNNPO1PPM ˖ $POUJOVBUJPO ˖ TVTQFOE$PSPVUJOF ˖ $PSPVUJOF%JTQBUDIFS ˖ %FGFSSFE ˖ 6ODPOOFE ˖ BOESPJE6* ˖ %FGBVMU%JTQBUDIFS ˖ 3FOEF[WPVT$IBOOFM ˖ 4FOE$IBOOFM ˖ 3FDFJWF$IBOOFM ˖ BDUPS ˖ SVO#MPDLJOH
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU ˖
$PSPVUJOF$POUFYU ˖ $PNNPO1PPM ˖ $POUJOVBUJPO ˖ TVTQFOE$PSPVUJOF ˖ $PSPVUJOF%JTQBUDIFS ˖ %FGFSSFE ˖ 6ODPOOFE ˖ BOESPJE6* ˖ %FGBVMU%JTQBUDIFS ˖ 3FOEF[WPVT$IBOOFM ˖ 4FOE$IBOOFM ˖ 3FDFJWF$IBOOFM ˖ BDUPS ˖ SVO#MPDLJOH ˖ KPJO
⢪$PSPVUJOFTך"1* ˖ MBVODI ˖ BTZOD ˖ BXBJU ˖ XJUI$POUFYU ˖
$PSPVUJOF$POUFYU ˖ $PNNPO1PPM ˖ $POUJOVBUJPO ˖ TVTQFOE$PSPVUJOF ˖ $PSPVUJOF%JTQBUDIFS ˖ %FGFSSFE ˖ 6ODPOOFE ˖ BOESPJE6* ˖ %FGBVMU%JTQBUDIFS ˖ 3FOEF[WPVT$IBOOFM ˖ 4FOE$IBOOFM ˖ 3FDFJWF$IBOOFM ˖ BDUPS ˖ SVO#MPDLJOH ˖ KPJO ˖
㢳ְ
ת׆כ㛇劤涸זהַֿ ׯה椚鍑׃ְ
MBVODI launch { println("thread:"+Thread.currentThread()) } MBVODIדDPSPUVJOF饯⹛ׅ
MBVODI launch { println("thread:"+Thread.currentThread()) } thread:Thread[ForkJoinPool.commonPool-worker-2,5,main] MBVODIדDPSPUVJOF饯⹛ׅ
MBVODI launch { println("thread:"+Thread.currentThread()) } thread:Thread[ForkJoinPool.commonPool-worker-2,5,main] ֿ̓ך5ISFBEכוַֿ勻 MBVODIדDPSPUVJOF饯⹛ׅ
MBVODI launch { println("thread:"+Thread.currentThread()) } thread:Thread[ForkJoinPool.commonPool-worker-2,5,main] MBVODIדDPSPUVJOF饯⹛ׅ MBVODIך⚥鋅ח遤ֲֿ
MBVODI ך⚥魦 public fun launch( context: CoroutineContext = DefaultDispatcher, start:
CoroutineStart = CoroutineStart.DEFAULT, parent: Job? = null, onCompletion: CompletionHandler? = null, block: suspend CoroutineScope.() -> Unit ): Job { 㹋כ$PSPVUJOF$POUFYUד㹋遤ׅ5ISFBEָ寸ת
MBVODI ך$PSPVUJOF$POUFYU public fun launch( context: CoroutineContext = DefaultDispatcher, start:
CoroutineStart = CoroutineStart.DEFAULT, parent: Job? = null, onCompletion: CompletionHandler? = null, block: suspend CoroutineScope.() -> Unit ): Job { 䒷侧ך$PSPVUJOF$POUFYUכرؿٕؓزד%FGBVMU%JTQBUDIFS 植朐כ%FGBVMU%JTQBUDIFSכ$PNNPO1PPM public val DefaultDispatcher: CoroutineDispatcher = CommonPool
MBVODI ך$PSPVUJOF$POUFYU public fun launch( context: CoroutineContext = DefaultDispatcher, start:
CoroutineStart = CoroutineStart.DEFAULT, parent: Job? = null, onCompletion: CompletionHandler? = null, block: suspend CoroutineScope.() -> Unit ): Job { $PNNPO1PPM public val DefaultDispatcher: CoroutineDispatcher = CommonPool
MBVODI ד⢪גְ $PNNPO1PPM object CommonPool : CoroutineDispatcher() { override fun
dispatch( context: CoroutineContext, block: Runnable ) = try { (pool ?: getOrCreatePoolSync()).execute(timeSource.trackTask(block)) } … $PNNPO1PPMך EJTQBUDIًاحسָㄎל
MBVODI ד⢪גְ $PNNPO1PPM object CommonPool : CoroutineDispatcher() { override fun
dispatch( context: CoroutineContext, block: Runnable ) = try { (pool ?: getOrCreatePoolSync()).execute(timeSource.trackTask(block)) } … 5ISFBE1PPMָזֽל⡲ծFYFDVUFֽׅ
知⽃ז %JTQBUDIFS⡲ג
鑐׃ח$PSPVUJOF%JTQBUDIFS ⡲ג class MyDispatcher : CoroutineDispatcher() { override fun dispatch(context:
CoroutineContext, block: Runnable) { println("dispatch:before") block.run() println("dispatch:after") } } launch(MyDispatcher()) { println("thread:"+Thread.currentThread()) } $PSPVUJOF%JTQBUDIFS竰䪫׃ؙٓأ⡲
鑐׃ח$PSPVUJOF%JTQBUDIFS ⡲ג class MyDispatcher : CoroutineDispatcher() { override fun dispatch(context:
CoroutineContext, block: Runnable) { println("dispatch:before") block.run() println("dispatch:after") } } launch(MyDispatcher()) { println("thread:"+Thread.currentThread()) } 荈ⴓד⡲%JTQBUDIFS䭷㹀ׅ
鑐׃ח$PSPVUJOF%JTQBUDIFS ⡲ג class MyDispatcher : CoroutineDispatcher() { override fun dispatch(context:
CoroutineContext, block: Runnable) { println("dispatch:before") block.run() println("dispatch:after") } } launch(MyDispatcher()) { println("thread:"+Thread.currentThread()) } EJTQBUDIًاحس㹋鄲׃ג
class MyDispatcher : CoroutineDispatcher() { override fun dispatch(context: CoroutineContext, block:
Runnable) { println("dispatch:before") block.run() println("dispatch:after") } } launch(MyDispatcher()) { println("thread:"+Thread.currentThread()) } EJTQBUDICFGPSF UISFBE5ISFBE<NBJO NBJO> EJTQBUDIBGUFS ךתתךأٖحسד 㹋遤דֹ
$PSPVUJOFTג5ISFBEה ずׄדכ
$PSPVUJOFTחכ ⚥倖ָ֮
⚥倖 class MyDispatcher : CoroutineDispatcher() { val executor = Executors.newSingleThreadExecutor()
override fun dispatch(context: CoroutineContext, block: Runnable) { executor.execute { println("dispatch:before") block.run() println("dispatch:after") } } } launch(MyDispatcher()) { println("1:" + Thread.currentThread()) suspendCoroutine<String> { continuation -> thread { // ී௨ʹthreadΛ࡞࣮ͬͯߦ͢Δ // தஅ͞ΕͨCoroutinesΛ࠶։͢Δ continuation.resume("test") } } println("2:" + Thread.currentThread()) } 㹋ꥷך⹛ֹח さׇ ➙㔐ך⢽דכ FYFDVUPS⢪ֲ
class MyDispatcher : CoroutineDispatcher() { val executor = Executors.newSingleThreadExecutor() override
fun dispatch(context: CoroutineContext, block: Runnable) { executor.execute { println("dispatch:before") block.run() println("dispatch:after") } } } launch(MyDispatcher()) { println("1:" + Thread.currentThread()) suspendCoroutine<String> { continuation -> thread { // ී௨ʹthreadΛ࡞࣮ͬͯߦ͢Δ // தஅ͞ΕͨCoroutinesΛ࠶։͢Δ continuation.resume("test") } } println("2:" + Thread.currentThread()) } TVTQFOE$PSPVUJOF ⢪ֲה DPSPVUJOFT⚥倖דֹ
class MyDispatcher : CoroutineDispatcher() { val executor = Executors.newSingleThreadExecutor() override
fun dispatch(context: CoroutineContext, block: Runnable) { executor.execute { println("dispatch:before") block.run() println("dispatch:after") } } } launch(MyDispatcher()) { println("1:" + Thread.currentThread()) suspendCoroutine<String> { continuation -> thread { // ී௨ʹthreadΛ࡞࣮ͬͯߦ͢Δ // தஅ͞ΕͨCoroutinesΛ࠶։͢Δ continuation.resume("test") } } println("2:" + Thread.currentThread()) } SFTVNF ⢪ֲהⱄדֹ
override fun dispatch(context: CoroutineContext, block: Runnable) executor.execute { println("dispatch:before") block.run()
println("dispatch:after") } } } launch(MyDispatcher()) { println("1:" + Thread.currentThread()) suspendCoroutine<String> { continuation -> thread { // ී௨ʹthreadΛ࡞࣮ͬͯߦ͢Δ // தஅ͞ΕͨCoroutinesΛ࠶։͢Δ continuation.resume("test") } } println("2:" + Thread.currentThread()) } ⚥倖ה⚥倖䖓ךⱄד 㔐5ISFBE1PPMד 㹋遤ׁגְ EJTQBUDICFGPSF 5ISFBE<QPPMUISFBE NBJO> EJTQBUDIBGUFS ͜͜ͰҰதஅ EJTQBUDICFGPSF 5ISFBE<QPPMUISFBE NBJO> EJTQBUDIBGUFS
"OESPJEד 㹋ꥷוֲ⢪ֲ
launch(UI) { val response = api.fetch() Snackbar.make(view, "code:${response.code}", Snackbar.LENGTH_LONG) .setAction("Action",
null).show() } "1*ַ《䖤׃גծךⰻ㺁4OBDLCBSח⳿ׅ⢽
launch(UI) { val response = api.fetch() Snackbar.make(view, "code:${response.code}", Snackbar.LENGTH_LONG) .setAction("Action",
null).show() } "1*ַ《䖤׃גծךⰻ㺁4OBDLCBSח⳿ׅ⢽ 6*ծծ
val UI = HandlerContext(Handler(Looper.getMainLooper()), “UI") public class HandlerContext( private val
handler: Handler, private val name: String? = null ) : CoroutineDispatcher(), Delay { … override fun dispatch(context: CoroutineContext, block: Runnable) { handler.post(block) } launch(UI) { val response = api.fetch() Snackbar.make(view, "code:${response.code}", Snackbar.LENGTH_LONG) .setAction("Action", null).show() } "OESPJEך)BOEMFS⡲
val UI = HandlerContext(Handler(Looper.getMainLooper()), “UI") public class HandlerContext( private val
handler: Handler, private val name: String? = null ) : CoroutineDispatcher(), Delay { … override fun dispatch(context: CoroutineContext, block: Runnable) { handler.post(block) } launch(UI) { val response = api.fetch() Snackbar.make(view, "code:${response.code}", Snackbar.LENGTH_LONG) .setAction("Action", null).show() } "OESPJEך)BOEMFSחQPTUֽׅ
launch(UI) { val response = api.fetch() Snackbar.make(view, "code:${response.code}", Snackbar.LENGTH_LONG) .setAction("Action",
null).show() }
launch(UI) { val response = api.fetch() Snackbar.make(view, "code:${response.code}", Snackbar.LENGTH_LONG) .setAction("Action",
null).show() } GFUDI ך⚥כ
launch(UI) { val response = api.fetch() Snackbar.make(view, "code:${response.code}", Snackbar.LENGTH_LONG) .setAction("Action",
null).show() } Api.kt interface ApiSearvice { @GET("/") fun fetchDeferrd(@Query("zipcode") zipCode: String = "1000000"): Deferred<Response> } val service = retrofit.create(ApiSearvice::class.java) suspend fun fetch(): Response { return service.fetchDeferrd().await() } 3FUSPUח״㹋鄲
launch(UI) { val response = api.fetch() Snackbar.make(view, "code:${response.code}", Snackbar.LENGTH_LONG) .setAction("Action",
null).show() } Api.kt interface ApiSearvice { @GET("/") fun fetchDeferrd(@Query("zipcode") zipCode: String = "1000000"): Deferred<Response> } val service = retrofit.create(ApiSearvice::class.java) suspend fun fetch(): Response { return service.fetchDeferrd().await() } SFUSPULPUMJODPSPVUJOFTBEBQUFS⢪ֲה %FGFSSFE鵤ׅ
launch(UI) { val response = api.fetch() Snackbar.make(view, "code:${response.code}", Snackbar.LENGTH_LONG) .setAction("Action",
null).show() } Api.kt interface ApiSearvice { @GET("/") fun fetchDeferrd(@Query("zipcode") zipCode: String = "1000000"): Deferred<Response> } val service = retrofit.create(ApiSearvice::class.java) suspend fun fetch(): Response { return service.fetchDeferrd().await() } %FGFSSFEכBXBJU ֿׅהד穠卓《䖤דֹ BXBJU ㄎעֿהדDPSPVUJOFTָ⚥倖׃גծ 0L)UUQך鸐⥋أٖحسד《䖤׃גծ 《䖤דֹ如痥ⱄׅկ
launch(UI) { val response = api.fetch() Snackbar.make(view, "code:${response.code}", Snackbar.LENGTH_LONG) .setAction("Action",
null).show() } Api.kt interface ApiSearvice { @GET("/") fun fetchDeferrd(@Query("zipcode") zipCode: String = "1000000"): Deferred<Response> } val service = retrofit.create(ApiSearvice::class.java) suspend fun fetch(): Response { return service.fetchDeferrd().await() } TVTQFOEًاحس⢪ֲהծ BXBJU 剅ַ׆חず劍涸ח《䖤׃גְ״ֲח剅ֽ ,PUMJOךط؎ذ؍ـזأة؎ٕכֿך剅ֹ倯 ˖ IUUQTHJUIVCDPN,PUMJOLPUMJODPSPVUJOFTCMPCNBTUFSLPUMJODPSPVUJOFTJOGPSNBMNEBTZODISPOPVTQSPHSBNNJOHTUZMFT
launch(UI) { val response = api.fetch() Snackbar.make(view, "code:${response.code}", Snackbar.LENGTH_LONG) .setAction("Action",
null).show() } Api.kt interface ApiSearvice { @GET("/") fun fetchDeferrd(@Query("zipcode") zipCode: String = "1000000"): Deferred<Response> } val service = retrofit.create(ApiSearvice::class.java) suspend fun fetch(): Response { return service.fetchDeferrd().await() } TVTQFOEًاحس⢪ֲחׂׂٓحف׃גְ ˖ IUUQTHJUIVCDPN,PUMJOLPUMJODPSPVUJOFTCMPCNBTUFSLPUMJODPSPVUJOFTJOGPSNBMNEBTZODISPOPVTQSPHSBNNJOHTUZMFT
ְְ椚鍑דֹ
תה ˖ $PSPVUJFOTכ5ISFBE♳ד⹛ֻծ⹛ֹכ然钠דֹ ˖ ⚥倖ָדֹגⱄָדֹ ˖ TVTQFOE⢪剅ֹ倯ד剅ְגְֻ