CompositionLocal LocalLifecycleOwner が存在しない問題の解決法
問題の原因
java.lang.IllegalStateException: CompositionLocal LocalLifecycleOwner not present
エラーは、Jetpack Composeアプリケーションで collectAsStateWithLifecycle()
や collectAsState()
を使用する際に発生します。具体的には以下の状況で発生します:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
// ここでエラーが発生
val uiState by mainViewModel.uiState.collectAsStateWithLifecycle()
}
}
}
根本的な原因:
- Lifecycleライブラリ(
androidx.lifecycle
)と Compose(androidx.compose
)のバージョン非互換性 LocalLifecycleOwner
が適切に初期化されていない- ProGuard/R8による最適化で必要なクラスが削除されるケース
このエラーのスタックトレースは以下のような形で表示されます:
java.lang.IllegalStateException: CompositionLocal LocalLifecycleOwner not present
at androidx.lifecycle.compose.LocalLifecycleOwnerKt$LocalLifecycleOwner$1.invoke(LocalLifecycleOwner.kt:26)
at ...
解決策
方法1: Lifecycleライブラリのアップデート(推奨)
問題はLifecycle 2.8.3以降で修正されており、これが最も確実な解決法です
build.gradle
でLifecycle関連ライブラリを更新:
dependencies {
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.3")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.3")
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.8.3")
// 他の依存関係はそのまま維持
}
- 同期後、クリーンビルドを実行:
./gradlew clean build
方法2: バージョンダウングレード(一時的対応)
すぐにアップデートできない場合、一時的な対応としてLifecycleを2.7.0にダウングレード:
dependencies {
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.7.0")
}
方法3: CompositionLocalProviderを使ったワークアラウンド
即時対応が必要な場合の一時的回避策:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
CompositionLocalProvider(
LocalLifecycleOwner provides this@MainActivity
) {
val uiState by mainViewModel.uiState.collectAsStateWithLifecycle()
// UIコンポーネント
}
}
}
}
注意点
Navigation Composeを使用している場合、各画面(ナビゲーション先)でこの修正が必要になります。
方法4: Proguard/R8設定(リリースビルド向け)
リリースビルドで特定のクラスが削除される場合、以下をproguard-rules.pro
に追加:
-keep public class androidx.compose.ui.platform.AndroidCompositionLocals_androidKt {
public static *** getLocalLifecycleOwner();
}
原因の詳細背景
この問題は主に、以下のバージョン組み合わせで発生します:
ライブラリ | 問題のあるバージョン | 安定バージョン |
---|---|---|
Lifecycle Runtime Compose | 2.8.0-2.8.2 | 2.8.3+ |
Compose BOM | 2024.05.00 | 最新安定版 |
変更点:
LocalLifecycleOwner
がandroidx.compose.ui
からlifecycle-runtime-compose
へ移動- バージョン非互換によりCompositionLocalが適切に初期化されない
ベストプラクティス
依存関係のバージョン整合性:
- Compose BOMとLifecycleライブラリの互換性を確認
- 定期的に依存関係を更新
バージョン管理の例:
// libs.versions.toml(推奨)
[versions]
composeBom = "2025.01.00" // 最新安定版
lifecycle = "2.8.3"
[libraries]
androidx-lifecycle-runtime-compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "lifecycle" }
- デバッグ時の確認事項:
./gradlew :app:dependencies
で依存関係ツリーを確認- 競合するバージョンがないかチェック
結論
CompositionLocal LocalLifecycleOwner not present
エラーを根本的に解決するには:
- Lifecycleライブラリを2.8.3以上に更新するのが最適解
- 即時対応が必要な場合は
CompositionLocalProvider
でワークアラウンド - リリースビルドではProGuard/R8設定を追加
- 依存関係のバージョン管理を厳密に行い、互換性問題を予防
最新のAndroid Studioと依存ライブラリを使用することで、この種の問題を未然に防げます。定期的な依存関係の更新とバージョン整合性のチェックを習慣づけましょう。