Coroutineとは?
Coroutineの概要
Coroutine(コルーチン)は、Kotlinで非同期処理を簡単に記述するための仕組みです。従来のスレッド管理とは異なり、軽量で効率的に非同期処理を実行できます。
Coroutineの主な特徴
- 軽量スレッド: 少ないリソースで複数の非同期タスクを実行可能
- 簡潔なコード: コールバックを使わず、直感的に非同期処理を記述
- スコープ管理:
CoroutineScope
を使用してタスクのライフサイクルを適切に管理 - 非同期処理の統合:
suspend
関数を使用して、処理の中断と再開をシンプルに実装可能
Coroutineの基本構造
Coroutineの起動
Coroutineは launch
や async
を使用して起動できます。
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
delay(1000L)
println("Coroutine実行完了")
}
println("メインスレッド処理")
}
launch
は新しいコルーチンを開始delay
は一時停止処理(スレッドブロックなし)runBlocking
はメインスレッドでのブロッキング動作
async と await を使った並列処理
async
を使用すると、複数の非同期処理を並列で実行し、結果を取得できます。
suspend fun fetchData(): String {
delay(2000L)
return "データ取得完了"
}
fun main() = runBlocking {
val result = async { fetchData() }
println("データ取得中...")
println(result.await())
}
Jetpack ComposeでのCoroutine活用
Composeにおける非同期処理
Jetpack Composeでは、LaunchedEffect
や rememberCoroutineScope
を使用して非同期処理を組み込むことが可能です。
LaunchedEffect の使用
LaunchedEffect
を利用すると、特定の状態が変化した際に非同期処理を実行できます。
@Composable
fun FetchDataScreen() {
var data by remember { mutableStateOf("読み込み中...") }
LaunchedEffect(Unit) {
data = fetchData()
}
Text(text = data)
}
LaunchedEffect(Unit)
はコンポーネントの初回描画時に実行fetchData()
はsuspend
関数として非同期実行
rememberCoroutineScope を使用したボタン処理
ボタンを押したときに非同期処理を開始する場合、rememberCoroutineScope
を活用できます。
@Composable
fun AsyncButtonScreen() {
val coroutineScope = rememberCoroutineScope()
var message by remember { mutableStateOf("ボタンを押してください") }
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Button(onClick = {
coroutineScope.launch {
message = fetchData()
}
}) {
Text("データ取得")
}
Text(text = message)
}
}
rememberCoroutineScope
を使うことで、ボタン押下時に非同期処理を実行launch
を使用して、非同期処理を開始
ViewModelとCoroutineの連携
ViewModelの作成
Jetpack Composeでは、ViewModelを使用してデータの状態を管理することが推奨されます。
class DataViewModel : ViewModel() {
private val _data = MutableStateFlow("データ未取得")
val data: StateFlow<String> = _data.asStateFlow()
fun fetchData() {
viewModelScope.launch {
_data.value = fetchData()
}
}
}
ViewModelをComposeに適用
collectAsState()
を使用して、ViewModelのデータをCompose UIで監視します。
@Composable
fun ViewModelScreen(viewModel: DataViewModel = viewModel()) {
val data by viewModel.data.collectAsState()
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Button(onClick = { viewModel.fetchData() }) {
Text("データ取得")
}
Text(text = data)
}
}
collectAsState()
を使用し、ComposeのUIが自動的に更新されるようにするviewModelScope.launch
で非同期処理を実行し、データを更新
非同期処理のエラーハンドリング
try-catch を使用したエラー処理
Coroutine内でエラーが発生した場合は、try-catch
を使用して適切に処理します。
suspend fun fetchDataSafe(): String {
return try {
delay(2000L)
"データ取得成功"
} catch (e: Exception) {
"エラー発生: ${e.message}"
}
}
CoroutineExceptionHandler の使用
CoroutineExceptionHandler
を使用すると、グローバルなエラーハンドリングが可能です。
val exceptionHandler = CoroutineExceptionHandler { _, exception ->
println("エラー: ${exception.message}")
}
fun main() = runBlocking {
val scope = CoroutineScope(SupervisorJob() + exceptionHandler)
scope.launch {
throw RuntimeException("テストエラー")
}
}
まとめ
- Coroutineは軽量で効率的な非同期処理を提供
LaunchedEffect
やrememberCoroutineScope
を使用してComposeに適用可能- ViewModelと組み合わせることで、データ管理をより適切に実装
- エラーハンドリングを適切に行い、安全な非同期処理を実装する
Jetpack ComposeとCoroutineを組み合わせることで、パフォーマンスの高いモダンなアプリ開発を実現できます。実際にコードを書いて試してみましょう!