モバイルアプリのライフサイクルは、アプリが起動、最小化、バックグラウンドからの復帰、終了時にどのように動作するかを決定します。この記事では、App Lifecycle(iOS)、Activity Lifecycle(Android)、Fragment Lifecycle、ViewController Lifecycle、LifecycleOwnerについて解説します。これらのプロセスを理解することは、メモリリーク、データ損失、アプリの誤動作を防ぐために非常に重要です。詳細はAndroid Activity Lifecycle 公式ドキュメントをご覧ください。
重要ポイント
個々の画面のライフサイクルに入る前に、アプリ全体のライフサイクルを理解することが重要です。iOSでは、アプリは5つの状態を経ます:Not Running(未実行)、Inactive(バックグラウンド、イベントを受信しない)、Active(アクティブ)、Background(バックグラウンド、コード実行中)、Suspended(バックグラウンド、コード一時停止)。これらの状態はAppDelegateでapplicationDidFinishLaunching、applicationDidBecomeActive、applicationWillResignActive、applicationDidEnterBackground、applicationWillTerminateメソッドを通じて管理されます。
Androidでは、これに相当するのがApplication Lifecycleで、Application.ActivityLifecycleCallbacksインターフェースを通じて追跡されます。ただし、AndroidはActivity(個々のアプリ画面)のライフサイクルに重点を置いています。これは、Androidアプリが複数のActivityで構成され、それぞれが独自のサイクルを持つためです。
Androidの現代的なアプローチは、lifecycle-processライブラリのProcessLifecycleOwnerを使用することです。これにより、特定のActivityに縛られることなく、プロセス全体の状態を追跡できます。iOSでは、アプリ状態の追跡にUISceneDelegate(iOS 13以降)またはAppDelegateが使用されます。SceneDelegateはiPad上の複数ウィンドウ(マルチウィンドウ)を処理します。App Lifecycleの理解は、バックグラウンド同期、ストリーミング、VoIP通話を伴うアプリを開発するIT Sectrにとって特に重要です。
ActivityはAndroidアプリの基本コンポーネントで、1つの画面を表します。Activityには明確に定義されたライフサイクルがあり、ユーザーアクションやシステムイベント(画面回転、着信、メモリ不足)に応じてオペレーティングシステムによって管理されます。
| メソッド | 説明 | 行うこと |
|---|---|---|
| onCreate | Activity作成時に一度呼び出される | UI初期化、findViewById、ViewModel設定 |
| onStart | Activityが表示可能になる | アニメーション開始、BroadCastReceiver登録 |
| onResume | Activityが入力フォーカスを取得 | カメラ、センサー、アニメーション開始 |
| onPause | Activityがフォーカスを失う(一部表示) | ドラフト保存、アニメーション停止 |
| onStop | Activityが非表示 | リソース解放、更新停止 |
| onDestroy | Activityが破棄される | 全参照クリア、LiveDataの購読解除 |
| onRestart | onStop後onStart前に呼び出される | 再初期化 |
重要:onSaveInstanceStateは一時的な状態を保存するためにonStopの前に呼び出されます。復元はonCreateのBundle savedInstanceState、またはViewModelのSavedStateHandleを通じて行われます。ライフサイクルを適切に処理しないと、画面回転時にアプリは未保存のデータをすべて失います。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString("draft", draftText)
}
override fun onDestroy() {
super.onDestroy()
// Отписка от всех подписок
}
}
Jetpack Composeでは、Activityのライフサイクルは変わりませんが、Composeは追加のツールを提供します:LifecycleOwnerによるライフサイクル対応コンポジション、破棄時の自動リソースクリーンアップのためのLifecycleEventEffectとDisposableEffect。
AndroidのFragmentはActivity内に存在し、独自のライフサイクルを持ちます。これはActivityと部分的に重複しますが、新しいメソッドを追加します。FragmentはActivityを破棄せずに追加、置換、削除できるため、より柔軟ですが、より複雑でもあります。
Fragment Lifecycleの主要メソッド: onAttach — FragmentがActivityにアタッチされる(最初の呼び出し);onCreate — データ初期化;onCreateView — View作成;onViewCreated — View作成完了、UI設定可能;onStart — Fragment表示;onResume — Fragmentフォーカス中;onPause — Fragmentフォーカス喪失;onStop — Fragment非表示;onDestroyView — View破棄;onDestroy — Fragment破棄;onDetach — FragmentがActivityからデタッチ。
Activityとの主な違い:onCreateViewとonDestroyViewは複数回呼び出される可能性があります(例:TabLayoutの切り替え時)。一方、onCreateは一度だけ呼び出されます。したがって、Viewの初期化はonCreateViewではなくonViewCreatedで行うべきです。Viewに関連するリソース(RecyclerViewアダプターなど)はonDestroyViewでクリーンアップする必要があります。
UIViewControllerはiOSで画面を管理するための基本クラスです。そのライフサイクルは、UIKitが自動的に呼び出す一連のメソッドで構成されています。このサイクルを理解することは、適切なUI初期化、データ管理、メモリ処理のために非常に重要です。
| メソッド | 呼び出しタイミング | 一般的な使用法 |
|---|---|---|
| loadView | View ControllerがView階層をロードする時 | ストーリーボードなしのカスタム初期化 |
| viewDidLoad | Viewがメモリにロードされた後(一度だけ) | UI設定、初期データ読み込み |
| viewWillAppear | Viewが画面に表示される前 | データ更新、通知の購読 |
| viewDidAppear | Viewが画面に表示された後 | アニメーション開始、トラッキングアニメーション開始 |
| viewWillDisappear | Viewが画面から消える前 | 状態保存、通知の購読解除 |
| viewDidDisappear | Viewが画面から消えた後 | アニメーション停止、リソース解放 |
| dealloc | View Controllerが破棄される時 | 全リソース解放 |
重要:viewDidLoadはView Controllerのライフタイム中に一度だけ呼び出されます。表示のたびにデータを更新するにはviewWillAppearを使用します。viewWillAppearでNotificationCenterを購読する場合は、メモリリークを避けるためにviewDidDisappearで必ず購読解除してください。
SwiftUIはView構造体を通じてViewのライフサイクルを管理します。コールバックメソッドの代わりに、SwiftUIはonAppearとonDisappear修飾子を使用します。グローバルなアプリ状態には、AppプロトコルとSceneプロトコルを通じてApp Lifecycleが使用されます。SwiftUIは状態に基づいてViewの作成と破棄を自動的に管理するため、開発が簡素化されますが、Viewのidentityとライフタイムを理解する必要があります。
struct ContentView: View {
var body: some View {
Text("Hello")
.onAppear {
print("View появилась")
}
.onDisappear {
print("View исчезла")
}
}
}
LifecycleOwnerはAndroid Architecture Componentsのインターフェースで、ライフサイクルを持つオブジェクト(Activity、Fragment)をマークします。LifecycleObserverは、オブジェクトがLifecycleOwnerのイベントを購読できるようにするインターフェースです。これらは、現代のAndroid開発におけるリアクティブなライフサイクル管理の基盤を形成します。
onStart/onStopで明示的にメソッドを呼び出す代わりに、DefaultLifecycleObserver(@OnLifecycleEventアノテーションを使用する非推奨のLifecycleObserverの代替)を使用することをお勧めします。これは、ActivityやFragmentへの直接参照を持たずにライフサイクルに反応する必要があるViewModelやその他のコンポーネントのためにGoogleが推進するアプローチです。
class MyObserver : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) {
// Подписка на обновления
}
override fun onStop(owner: LifecycleOwner) {
// Отписка
}
}
IT Sectrでは、すべてのAndroidプロジェクトでLifecycleOwnerを使用しています。ViewModelはviewModelScopeとlifecycleScopeを介してActivityのLifecycleOwnerを購読し、Activityが破棄されたときにコルーチンが自動的にキャンセルされることを保証します。これによりメモリリークが防止され、コードがよりクリーンで安全になります。
よくある質問
Activityは6つの状態を経ます:Created(onCreate)、Started(onStart)、Resumed(onResume)、Paused(onPause)、Stopped(onStop)、Destroyed(onDestroy)。
順序:loadView → viewDidLoad → viewWillAppear → viewDidAppear → viewWillDisappear → viewDidDisappear。viewDidLoadは一度だけ呼び出されます。
LifecycleOwnerはAndroid Architecture Componentsのコンポーネントで、ActivityまたはFragmentのライフサイクルを所有します。LifecycleObserverを介してイベントを購読できます。
iOSアプリは5つの状態を経ます:Not Running、Inactive、Active、Background、Suspended。遷移はUIApplicationDelegateを介して管理されます。
Saved Stateは、画面回転やプロセス再作成時にActivity/Fragmentの状態を保持するAndroidのメカニズムです。onSaveInstanceStateとSavedStateHandleを使用します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。