0
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?

【Jetpack Compose】ライフサイクル完全に理解した(気がする)!コンポーザブルの一生を追ってみた

Posted at

はじめに

こんにちは!
Android開発で地味に頭を悩ませるのが、ActivityやFragmentの複雑なライフサイクルですよね...。onCreateやらonStartやらonDestroyViewやら...(正直今でも時々混乱します w)

最近Jetpack Composeを触っているのですが、このライフサイクルの考え方がガラッと変わって、最初は少し戸惑いました。
ですが、慣れてくるとComposeのライフサイクルは非常にシンプルで、**「誕生」「変化」「消滅」**の3つだけなんだな、ということが分かってきました。

今回は、僕自身の復習も兼ねて、@Composable関数(コンポーザブル)が画面に表示されてから消えるまでの「一生」を、この3つの状態で整理してみたいと思います。


状態1:Compositionへの参加(誕生の瞬間)

これは、コンポーザブルが初めて画面に描画されるタイミングです。
if文の条件が満たされたり、画面が最初に表示されたりした時に、僕たちが書いた@Composable関数が呼び出されます。

  • ざっくり言うと: Composeの世界に「初めまして!」と登場する瞬間ですね。Composeは内部でUIの構成をツリー構造で管理しているのですが、そこに新しいノードとして追加されるイメージです。
  • 昔のViewシステムで言うと: FragmentonCreateView()でレイアウトを読み込んで、UIを構築するプロセスにちょっと似てるかもしれません。

🔑 ここでのポイント

この「誕生」の処理は、UIの初期状態を作る大事な部分です。ただ、ここで注意したいのが、「この処理は最初の一回しか呼ばれないだろう」と思い込まないことです。なぜなら、次にお話しする「再コンポーズ」が、Composeの日常茶飯事だからです(笑)。


状態2:再コンポーズ(成長と変化)

さて、ここがComposeの肝であり、最初のうちは一番「???」となる部分、**再コンポーズ(Recomposition)**です。
簡単に言うと、状態(State)が変わったのをきっかけに、コンポーザブルがもう一度呼び出されて、画面の一部が更新されることです。

remember { mutableStateOf(...) }で定義した状態をコンポーザブルが使っていると、その値が変わった瞬間に、Composeが「お、データが変わったな!じゃあ見た目も変えなきゃ!」と、関係する部分だけを賢く再描画してくれます。

  • ざっくり言うと: 監督が俳優に「もっと驚いた表情で!」と指示を出すような感じです。俳優は舞台から降りたりせず、その場で表情の演技だけをやり直します。
  • 昔のViewシステムで言うと: TextViewの文字を変えるためにtextView.setText("新しいテキスト")と手動で命令していたアレです。Composeでは、状態を変えるだけで、この面倒なUI更新を全自動でやってくれます。めちゃくちゃ楽です。

🔑 ここでのポイント

再コンポーズは、僕たちが思っている以上に頻繁に、そして高速に実行されます。なので、いくつか守らないとパフォーマンスが落ちる「お作法」があります。

  • 重い処理は絶対ダメ!: 再コンポーズはアニメーション中なら1秒間に60回呼ばれることもあります。ここでDBアクセスやネットワーク通信なんて書いたら…考えるだけで恐ろしいですね(笑)。重い処理は全部ViewModelに任せましょう。
  • 副作用のない作りにする: @Composable関数は、同じ状態を渡されたら、いつ呼ばれても同じUIを返すように作るのが理想です。
  • Composeは意外とサボる: もし渡されるデータが変わっていなければ、Composeは「あ、これ前と同じだな」と判断して、再コンポーズを賢くスキップします。これがComposeのパフォーマンスが高い理由の一つです。

状態3:Compositionからの退出(消滅の瞬間)

最後に、コンポーザブルが画面から不要になって破棄されるタイミングです。
if文の条件が外れたり、別の画面に遷移したりして、UIが表示されなくなった時に発生します。UIツリーから、そのコンポーザブルは静かに消え去ります。

  • ざっくり言うと: 映画の撮影が終わって、俳優がセットから帰っていくイメージです。「お疲れ様でしたー!」って感じですね。
  • 昔のViewシステムで言うと: FragmentonDestroyView()が一番近いです。UIが見えなくなるので、後片付けをするタイミングです。

🔑 ここでのポイント

ほとんどの場合、コンポーザブルはただ消えるだけでOKです。でも、もし「誕生」の時に、外部のリソース(センサーの監視を開始した、など)を使い始めた場合は、「消滅」の時にそれを解放する後片付けが絶対に必要です。これを忘れると、メモリリークという名の恐ろしいバグの原因になります。

この「消滅」のタイミングを捕まえるために、ComposeはDisposableEffectという仕組みを用意してくれています。

DisposableEffect(Unit) {
    // 誕生した時の処理
    startSomeListener()

    onDispose {
        // 消滅する時の後片付け
        stopSomeListener() // ← これを忘れると大変なことに…!
    }
}

まとめ
というわけで、コンポーザブルの一生をざっと追いかけてみました。

状態 🎬 ざっくり言うと 従来のViewシステムで言うと 🔑 役割
参加 (誕生) 俳優がセットに入る onCreateView UIの初期描画
再コンポーズ (変化) 監督の指示で再演技 手動でのUI更新 状態に応じたUIの差分更新
退出 (消滅) 俳優がセットから出る onDestroyView リソースの解放

この「状態が変われば、UIも勝手に変わる」という宣言的な考え方に慣れるのが、Composeを使いこなす第一歩なのかなと感じています。
ここまで読んでいただきありがとうございました!

0
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
0
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?