Zenn
Closed5

Flutter エンジニア向け Android の Activity とライフサイクルの基礎知識

高田 晴彦高田 晴彦

(社内勉強会向けの資料です)

モチベーション

  • Android ネイティブ未経験の Flutter エンジニアに向けて、Android の Activity とライフサイクルについて簡単に解説
  • Flutter で作った Android アプリがどのように動いているのか、より納得感を持って開発する
  • Add-to-app を使っている場合、つなぎ込みの担当者は、どのような開発を行っているのか理解する
  • camera パッケージなど、ライフサイクルに密接に関わるパッケージを使った開発において、挙動をイメージしやすくする
高田 晴彦高田 晴彦

Activity

  • Android のいわゆる画面
  • スタックのように積むことができて、バックキーや finish() メソッド呼び出しで、今見えている画面を取り除くことで、前の画面に戻れる
  • ランチャーアイコンから起動できる Android アプリには、必ず1つ以上ある

Flutter アプリにおける Activity

  • Flutter を描画する FlutterActivity が、かならず1つ以上ある。
  • Flutter プロジェクトだと android ディレクトリの奥深くにある MainActivity が該当する。
高田 晴彦高田 晴彦

ライフサイクル

Activity にはライフサイクルがある

ライフサイクル名 内容
onCreate Activity が作られた。アプリ起動時や、別の画面から呼ばれたときが該当する。
onResume Activity がフォアグランドになった。上に被さっている Activity が終了したときや、別のアプリから切り替えた時が該当する。
onPause Activity がバックグランドになった。ホームボタンを押したり、別の Activity が上に被さった時が該当する。
onDestory Activity が破棄された。バックキーで前の画面に戻った場合が該当する。

厳密には onStart と onStop があるが省略。

Flutter アプリにおける Android のライフサイクル

通常は気にしなくて良いが、カメラや GPS など、デバイスの機能を使う場合は、意識する必要がある。
camera パッケージにはこのような解説がある。

class _CameraScreenObserver extends WidgetsBindingObserver {
    
    void didChangeAppLifecycleState(AppLifecycleState state) {
      final CameraController? cameraController = controller;
    
      // App state changed before we got the chance to initialize.
      if (cameraController == null || !cameraController.value.isInitialized) {
        return;
      }
    
      if (state == AppLifecycleState.inactive) { // Android の onPause に該当
        cameraController.dispose();
      } else if (state == AppLifecycleState.resumed) {  // Android の onResume に該当
        _initializeCameraController(cameraController.description);
      }
  }
}

上記インスタンスをこのように使う。

WidgetsBinding.instance.addObserver(this);
WidgetsBinding.instance.removeObserver(this);

Flutter でライフサイクルを無視した場合

カメラの場合、ホームボタンを押してアプリをバックグランドにして、別のアプリを開いたとする。その別アプリがカメラを使いたくても、カメラを掴んだままなので、使えなくなる。
バックグランドになったタイミングで解放する必要がある。

高田 晴彦高田 晴彦

画面遷移

Android においては3種類ある。

  • Activity 呼び出しによる画面遷移
  • Fragment による画面遷移
  • Compose による画面遷移

Activity

  • Intent を作って startActivity 関数で上に被せることができる。
val intent = Intent(this, MemberActivity::class.java)
intent.putInt("userId", 123) // 引数も渡せる
startActivity(intent)
  • Activity が結果を持つことができる。
  • 閉じたときに結果を受け取る方法もある。
val data = Intent()
data.putBoolean("favorite", true)
setResult(RESULT_OK, data)
  • いいね問題の古典的な解決に使える

https://www.docswell.com/s/tfandkusu/54VNNW-LikeProblem#p6

Fragment

  • Activity 内の矩形で Activity と同様のライフサイクルがある
  • Fragment は単独では存在できない。かならず Activity に載っている。
  • Activity の中で Fragment を切り替えたり、積むことができる
  • 誕生の経緯は 2011年リリースのタブレット用 OS - Android 3.0。リストと詳細 Fragment にして、スマホでは別に使い、タブレットでは横に並べて使うことを想定。
  • ボトムナビゲーションのボタンを押して表示を切り替えている部分は、表示 Fragment を切り替えている。

Compose

  • 2021年に安定版がリリースされた、宣言的 UI フレームワークによる画面遷移
  • それより前の Android 1.0 からあった UI フレームワークは View や XML レイアウトと呼ばれる
  • 必ず Activity に載っている
    • Activity に載っている Fragment に載っていることもある。

Flutter の Add-to-app においては

  • FlutterActivity から別の Activity を呼び出す
  • View や Compose で作った Activity から FlutterActivity を呼び出す
  • FlutterFragment もある
高田 晴彦高田 晴彦

Jetpack

  • Activity, Fragment は OS に標準搭載されている Android SDK に実装されているが、直接それらを使うことは無い。
  • Jetpack という Google 標準のライブラリ群を使う
  • OS アップデートにより SDK の使い方が変わることがあるが、Jetpack が吸収する
  • 便利な機能が追加されている
  • 分かりやすいものだと Edge-to-edge。中のソースコードを見ると OS バージョン別分岐がすごい。
このスクラップは2ヶ月前にクローズされました
作成者以外のコメントは許可されていません