Kotlin入門シリーズ:Coroutine協程
13136 ワード
1協程の概念と基本的な使用
1.1協業とは
コモン
1.2コンシステントの基本使用
コパスを使用する場合、一般的には、関数
実際の開発では,ネットワーク要求が時間のかかる操作を実行し,結果を得てUIを更新することが多く,スレッド切替には
2 suspendサスペンション
2.1契約の保留とは
掛けてあるのは何ですか.掛けてあるのは協程です.上で説明した協程は
2.2 suspendの役割
2.2.1 suspendサスペンション関数がコモンまたは別のサスペンション関数で呼び出される理由
上記のコードでは、
上の説明から分かるように、保留するには
2.2.2 suspendキーワードの役割は何ですか
上記の分析によると、
Javaを書くときに中のコードがメインスレッドで関数操作を呼び出していることに気づかないと、スレッドカートンやANRになります.Kotlinで
3非ブロックサスペンション
3.1非ブロックサスペンションとは
非ブロック式ですが、実はスレッドが詰まっていません.Kotlinの保留関数を使ってスレッドを切るにしても、JavaのThreadでスレッドを切るにしても、実は非ブロック式です.
したがって、コヒーレントな非ブロック式サスペンションは、実際にはブロック方式で非ブロックのコードを書いただけで、本質的に時間のかかる操作なのかスレッドを切らなければならないのか、更新インタフェースなのか、受賞者スレッドなのか(いずれのコードもブロックされているが、時間のかかる操作のコードは人間の感知の中で明らかであるだけだ).
3.2スレッドとスレッドの関係
Kotlinでは、Javaの
4まとめコパスは、スレッド である.が掛けられているのは、自動的に切り取ることができるスレッド である.非ブロック式は、ブロックされているように見えるコードで非ブロックの動作 を書くことができるコヒーレンスである.
1.1協業とは
コモン
Coroutine
は、実際にはKotlinで提供されているスレッドAPIのセットであり、スレッドにあまり関心を持たなくても簡単に同時操作を書くことができます(すなわち、コモンはスレッドフレームワークであり、Kotlinでスレッドを便利に使用することができます.同じコードブロックで何度もスレッドを切り替えることができるのが便利です).1.2コンシステントの基本使用
コパスを使用する場合、一般的には、関数
launch()
を使用してコパスを作成し、launch()
関数で切り替えるスレッドを指定します.一般的には、バックグラウンドスレッドとプライマリスレッドを表すDispatchers.IO
とDispatchers.Main
があります.launch()
関数ブロックに包まれたコードは、コヒーレントである.//
launch(Dispatchers.IO) {
saveToDatabase(data)
}
//
launch(Dispatchers.Main) {
updateViews(data)
}
// Thread
thread {
...
}
実際の開発では,ネットワーク要求が時間のかかる操作を実行し,結果を得てUIを更新することが多く,スレッド切替には
withContext()
を用いてスレッドの切替を行うこともでき,実行が完了すると自動的にスレッドを切り替えることができる,これがコラボレーションである.// , !!!
launch(Dispatchers.IO) {
val user = api.getUser()
launch(Dispatchers.Main) {
nameTv.text = user.name
}
}
//
// Coroutine
launch(Dispatchers.Main) {
// withContext()
val user = withContext(Dispatchers.IO) {
api.getUser() // :
}
withContext(Dispatchers.IO) { ... }
withContext(Dispathers.IO) { ... }
...
nameTv.text = user.name // UI:
}
// withContext()
launch(Dispatchers.Main) {
val user = suspendingGetUser()
nameTv.text = user.name
}
suspend fun suspendingGetUser() {
withContext(Dispatchers.IO) {
api.getUser()
}
}
launch(Dispatchers.Main) {
val avatar = async { api.getAvatar(user) } //
val logo = async { api.getCompanyLogo(user) } // logo
val merged = suspendingMerge(avatar, logo) //
show(merged) //
}
2 suspendサスペンション
2.1契約の保留とは
掛けてあるのは何ですか.掛けてあるのは協程です.上で説明した協程は
launch()
関数に包まれたコードであり、コードが保留関数に実行されると、協程は現在のスレッドから保留されます.コプロセッサが操作を実行すると、スレッドは自動的に現在のスレッドに戻されます(簡単に理解すると、実際にはスレッドが切断され、具体的には後で自動的に切り替えられるスレッドが切り替えられます).launch(Dispatchers.Main) {
// launch() ,
// suspendingGetImage() ,
// , suspendingGetImage() ,
// ,
// ?suspendingGetImage() Dispatchers.IO
// ? , Dispatchers.IO Dispatchers.Main
val image = suspendingGetImage(imageId)
avatarIv.setImageBitmap(image)
}
// suspend
suspend fun suspendingGetImage(imageId: String) {
witchContext(Dispatchers.IO) {
api.getImage(imageId)
}
}
2.2 suspendの役割
2.2.1 suspendサスペンション関数がコモンまたは別のサスペンション関数で呼び出される理由
上記のコードでは、
launch()
でsuspendingGetImage()
を使用しているときに、suspend
キーワードがIDEでエラーを報告していないと、保留関数がコモンで呼び出されるか、別の保留関数で呼び出されるかを示すメッセージが表示されます.上の説明から分かるように、保留するには
resume
を復元する必要があり、関数切替スレッドを保留した後にスレッドを切替戻す必要がありますが、resumeという機能を復元するにはコヒーレンスなので、1つの保留関数がコヒーレンスで呼び出されなければ、関数切替スレッドを保留した後にスレッドを再切替することはできません.2.2.2 suspendキーワードの役割は何ですか
suspend fun suspendingPrint() {
println("Thread: ${Thread.currentThread().name}")
}
suspend fun suspendingGetImage(imageId: String) {
withContext(Dispatchers.IO) {
api.getImage(imageId)
}
}
launch(Dispatchers.Main) {
// Main , ,
// , , suspendingGetImage() , withContext(Dispatchers.IO)
// suspend
suspendingPrint()
}
上記の分析によると、
suspend
キーワードはスレッドを閉じる機能やスレッドを切り替える役割を果たしていないが、それはいったい何に使われているのだろうか.suspend
キーワードは、関数の作成者が関数の呼び出し者に注意するために使用される.suspend
キーワード宣言のサスペンション関数は時間のかかる操作であり、関数の作成者はサスペンション方式で操作をバックグラウンドで実行しているので、関数の呼び出し者にこの関数を呼び出してください.Javaを書くときに中のコードがメインスレッドで関数操作を呼び出していることに気づかないと、スレッドカートンやANRになります.Kotlinで
suspend
キーワードで保留関数を宣言して呼び出し者にこの関数が時間のかかるバックグラウンドで実行されるタスクであることを警告すれば、このようなメインスレッドで時間のかかる操作を呼び出す問題を回避することができます.3非ブロックサスペンション
3.1非ブロックサスペンションとは
非ブロック式ですが、実はスレッドが詰まっていません.Kotlinの保留関数を使ってスレッドを切るにしても、JavaのThreadでスレッドを切るにしても、実は非ブロック式です.
したがって、コヒーレントな非ブロック式サスペンションは、実際にはブロック方式で非ブロックのコードを書いただけで、本質的に時間のかかる操作なのかスレッドを切らなければならないのか、更新インタフェースなのか、受賞者スレッドなのか(いずれのコードもブロックされているが、時間のかかる操作のコードは人間の感知の中で明らかであるだけだ).
3.2スレッドとスレッドの関係
Kotlinでは、Javaの
Executors
とAndroidのHandler
APIに似たスレッドによって実現されるより上位レベルのツールAPIフレームワークです.コヒーレンスの本質はスレッドです.4まとめ