1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Android】Jetpack Compose と Activity ライフサイクルを徹底理解する

1
Posted at

はじめに

― 再コンポーズの正体から、Compose 的ライフサイクル、Activity との関係まで ―

Android UI 開発は、従来の XML + Activity/Fragment から、Jetpack Compose を中心とした新しい世界へ完全に移行しつつあります。しかし、古くからある Activity のライフサイクル と、Compose の Recomposition(再コンポーズ) はまったく別軸で動きます。

初学者はもちろん、経験者でも混乱しやすい部分です。
この記事では、両者の役割の違い → Compose がどう UI を再描画するか → Activity とどう連携するのか を “実務ベースの視点” でわかりやすく整理します。


1. Activity ライフサイクルの復習(でも本質だけ)

Android の Activity は「画面そのもののライフサイクル」を管理します。

主なコールバックは以下:

状態 説明
onCreate() UI 構築の準備。Compose ならここで setContent() を呼ぶ
onStart() 画面が見える直前
onResume() 画面がユーザー操作可能になる
onPause() フォーカス喪失。画面は見えているが操作不可になる可能性
onStop() 完全に見えない状態
onDestroy() Activity が破棄される

ポイント:Activity は “UI の舞台の管理者”。
UI 描画そのものには関与しない。


2. Compose のライフサイクル(Activity とは別世界)

Compose は「宣言的 UI」。
UI は “状態” によって勝手に変わる世界です。

Compose の UI には 3 つの段階があります:

Composition

初めて Composable が呼ばれ、UI ツリーが構築される。

Recomposition(再コンポーズ)

状態(State)が変化した時、必要な部分だけ UI が再描画される。

→ これが多くの人が混乱するポイント
→ Activity の onResume() とかとは無関係!

Disposal

UI ツリーのノードが不要になった時、Compose が破棄する。

ポイント:Recomposition は「部分更新」であり、「破壊して再構築」ではない。


3. Activity と Compose の関係性は?

これは超重要なので、シンプルに例える。

Activity:家そのもの
Compose:部屋の家具
Recomposition:家具の配置換え

つまり:

  • Activity が破壊されれば(例:画面回転)
    → Compose の UI も作り直し(Composition からやり直し)
  • Compose 内の状態変更
    → 部分的 UI 更新(Recomposition)
    → Activity には何も起こらない

4. Activity 再生成時に Compose はどうなるか?

例えば画面回転などの configuration change が起きると:

  1. Activity 再生成
  2. setContent{} が再実行
  3. Compose ツリーも再生成
  4. 全 UI の Composition がやり直し

ただし、

rememberSaveable を使えば状態保持可能

var text by rememberSaveable { mutableStateOf("") }

Bundle + SavedStateHandle 経由で状態が維持される。


5. 副作用の管理は Compose 独自ライフサイクルで行う

Activity に合わせて動く必要があるコードも Compose 内には存在する。
そのための仕組みが:

  • LaunchedEffect
  • DisposableEffect
  • SideEffect
  • rememberUpdatedState

LaunchedEffect:Compose が Composition に入った瞬間だけ実行

@Composable
fun LoadOnce() {
    LaunchedEffect(Unit) {
        println("Load once when composed")
    }
}

DisposableEffect:Composition から外れると cleanup

DisposableEffect(Unit) {
    println("Start")
    onDispose {
        println("Cleanup")
    }
}

rememberUpdatedState:最新値を常に保持する

イベントリスナーやコールバックで使うと超重要。


6. Activity と連携したい(LifecycleOwner / repeatOnLifecycle)

Compose だけでは Activity の状態はわからない。
その橋渡しをしてくれるのが LocalLifecycleOwnerrepeatOnLifecycle

例:Activity が STARTED の間だけ ViewModel を購読する

@Composable
fun MyScreen(viewModel: MyViewModel = viewModel()) {
    val lifecycleOwner = LocalLifecycleOwner.current

    LaunchedEffect(Unit) {
        lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
            viewModel.loadData()
        }
    }
}

これは実務で超使うパターン。


7. Compose の落とし穴(経験者もやりがち)

❌ ① Composable 内でログや処理を書いてしまう

@Composable
fun Bad() {
    println("This is called many times!")
}

Recomposition のたびに呼ばれまくる。

正解

副作用は LaunchedEffect / DisposableEffect に寄せる。


まとめ

  • Activity は 画面そのもののライフサイクル管理者
  • Compose は 宣言的 UI + 状態に応じた差分レンダリング
  • Activity のコールバックと Recomposition は 関係ない
  • 画面回転などで Activity 再生成 → Compose も Composition からやり直し
  • 状態保持には rememberSaveable
  • 副作用には LaunchedEffect / DisposableEffect
  • Activity と連携したいときは repeatOnLifecycle

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?