Skip to content

CompositionLocal LocalLifecycleOwner が存在しない問題の解決法

問題の原因

java.lang.IllegalStateException: CompositionLocal LocalLifecycleOwner not present エラーは、Jetpack Composeアプリケーションで collectAsStateWithLifecycle()collectAsState() を使用する際に発生します。具体的には以下の状況で発生します:

kotlin
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以降で修正されており、これが最も確実な解決法です

  1. build.gradle でLifecycle関連ライブラリを更新:
kotlin
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")
    // 他の依存関係はそのまま維持
}
  1. 同期後、クリーンビルドを実行:
./gradlew clean build

方法2: バージョンダウングレード(一時的対応)

すぐにアップデートできない場合、一時的な対応としてLifecycleを2.7.0にダウングレード:

kotlin
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を使ったワークアラウンド

即時対応が必要な場合の一時的回避策:

kotlin
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 Compose2.8.0-2.8.22.8.3+
Compose BOM2024.05.00最新安定版

変更点:

  • LocalLifecycleOwnerandroidx.compose.uiからlifecycle-runtime-composeへ移動
  • バージョン非互換によりCompositionLocalが適切に初期化されない

ベストプラクティス

  1. 依存関係のバージョン整合性:

    • Compose BOMとLifecycleライブラリの互換性を確認
    • 定期的に依存関係を更新
  2. バージョン管理の例:

kotlin
// 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" }
  1. デバッグ時の確認事項:
    • ./gradlew :app:dependenciesで依存関係ツリーを確認
    • 競合するバージョンがないかチェック

結論

CompositionLocal LocalLifecycleOwner not presentエラーを根本的に解決するには:

  1. Lifecycleライブラリを2.8.3以上に更新するのが最適解
  2. 即時対応が必要な場合はCompositionLocalProviderでワークアラウンド
  3. リリースビルドではProGuard/R8設定を追加
  4. 依存関係のバージョン管理を厳密に行い、互換性問題を予防

最新のAndroid Studioと依存ライブラリを使用することで、この種の問題を未然に防げます。定期的な依存関係の更新とバージョン整合性のチェックを習慣づけましょう。