rxjava-to-coroutines-migration について
AndroidやKotlinのコードをRxJavaからKotlin CoroutinesとFlowへ安全に移行するためのスキルです。型やオペレーターの対応表に加え、購読、エラー、スレッド、ライフサイクルの扱い方を説明します。
主な機能
- 01RxJava型からコルーチンへの対応表
- 02SubjectからホットFlowへの対応
- 03スケジューラーとオペレーターの変換
- 04移行手順とコード例
- 05ライフサイクルを考慮したFlow収集
活用シーン
- 01RxJavaのデータソースをsuspend関数またはFlowに変換
- 02RxJavaのオペレーターと購読を置き換え
- 03エラー処理とスレッド処理を更新
- 04ライフサイクルに応じてFlowを収集
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ new-silvermoon/ awesome-android-agent-skills --skill rxjava-to-coroutines-migrationインストール後、Claude Code で/rxjava-to-coroutines-migrationを入力して読み込まれたか確認します。
詳細
RxJava から Kotlin Coroutines への移行スキル
Android または Kotlin のコードベースを、RxJava から Kotlin Coroutines と Flow へ安全かつ慣用的にリファクタリングするための、専門的なスキルです。
移行マッピングガイド
RxJava のコンポーネントを Kotlin Coroutines に移行する際は、次の標準的なマッピングを使用します。
1. 基本型
Single<T>->suspend fun ...(): T- 単一の非同期値です。
Maybe<T>->suspend fun ...(): T?- 存在しない場合もある、単一の非同期値です。
Completable->suspend fun ...()- 値を返さずに完了する非同期処理です。
Observable<T>->Flow<T>- コールドな値のストリームです。
Flowable<T>->Flow<T>- Coroutines の Flow はバックプレッシャーをネイティブに処理します。
2. Subject からホットフローへ
PublishSubject<T>->MutableSharedFlow<T>- 複数のサブスクライバーにイベントをブロードキャストします。バッファリングが必要な場合は、
MutableSharedFlow(extraBufferCapacity = ...)を使用します。
- 複数のサブスクライバーにイベントをブロードキャストします。バッファリングが必要な場合は、
BehaviorSubject<T>->MutableStateFlow<T>- 状態を保持し、新しいサブスクライバーに現在または最新の値を出力します。初期値が必要です。
ReplaySubject<T>->MutableSharedFlow<T>(replay = N)- 新しいサブスクライバーに、出力済みの直近 N 個の値を再出力します。
3. Scheduler から Dispatcher へ
Schedulers.io()->Dispatchers.IOSchedulers.computation()->Dispatchers.DefaultAndroidSchedulers.mainThread()->Dispatchers.Main- コンテキストの切り替え:
subscribeOnとobserveOnは通常、withContext(Dispatcher)または Flow のflowOn(Dispatcher)に置き換えます。
4. オペレーター
map->mapfilter->filterflatMap->flatMapMerge(並行)またはflatMapConcat(逐次)switchMap->flatMapLatestdoOnNext/doOnSuccess->onEachonErrorReturn/onErrorResumeNext->catch { emit(...) }startWith->onStart { emit(...) }combineLatest->combinezip->zipdelay->delay(サスペンド関数)またはonEach { delay(...) }
5. 実行とライフサイクル
subscribe()-> Flow の場合はcollect {}、サスペンド関数の場合はCoroutineScope内で直接呼び出します。Disposable.dispose()->Job.cancel()CompositeDisposable.clear()-> 親のCoroutineScopeまたはJobをキャンセルします。
実行手順
- RxJava のチェーンを分析する: ソース型(Single、Observable など)、使用されているオペレーター、サブスクリプションが行われる場所を特定します。
- ソースを変換する: まずリポジトリ層またはデータソース層の戻り値の型を変更します。単発の処理は
suspend関数に、ストリームはFlowに変換します。 - オペレーターを書き換える: RxJava のオペレーターを、Flow または Coroutine の同等の処理に置き換えます。多くの RxJava オペレーターは、
mapまたはonEachブロック内の標準的な Kotlin コレクション/シーケンス操作にそのまま置き換えられることに注意してください。 - サブスクリプションを更新する: ViewModel または Presenter で、
.subscribe(...)をlaunch { ... }と.collect { ... }に置き換えます。起動処理が適切なライフサイクルスコープ(例:viewModelScope)に紐付いていることを確認します。 - エラーを処理する:
onErrorブロックを、サスペンド関数を囲むtry/catch、または Flow の.catch { }オペレーターに置き換えます。 - スレッド処理を行う:
.subscribeOn()と.observeOn()を削除します。必要に応じてwithContextを使用するか、上流のフローのコンテキストを変更するために.flowOn()を使用します。
変換例
RxJava:
fun getUser(id: String): Single<User> { ... }
disposable.add(
getUser("123")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ user ->
view.showUser(user)
}, { error ->
view.showError(error)
})
)
Coroutines/Flow:
suspend fun getUser(id: String): User { ... } // Internally uses withContext(Dispatchers.IO) if needed
viewModelScope.launch {
try {
val user = getUser("123")
view.showUser(user)
} catch (e: Exception) {
view.showError(e)
}
}
ベストプラクティス
- サスペンド関数を優先する: 複数の値が時間の経過とともに実際に流れる場合を除き、
Flowではなくsuspend関数を基本とします。SingleとCompletableは、ほとんどの場合suspend関数になります。 - 状態の処理:
BehaviorSubjectやLiveDataの代わりに、ViewModel でStateFlowを使用して UI に状態を公開します。 - ライフサイクルへの対応: UI レイヤーで Flow を収集する際は、ビューが表示されていない間のバックグラウンド処理を避けるために、
repeatOnLifecycleまたはflowWithLifecycleを使用します。
コメント
Markdown 対応