App Lifecycle:iOSとAndroidにおけるアプリの状態とは

著者: IT Sectr 公開日: 2026-03-02 読了時間: 8 分
App Lifecycle(アプリケーションのライフサイクル)とは、モバイルアプリが起動から終了までに経由する一連の状態のことです。ライフサイクルを理解することは、リソース管理、データ永続化、安定性の確保に不可欠です。iOSでは、アプリは次の状態を経由します:Not Running → Active → Inactive → Background → Suspended。Androidでは — onCreate → onStart → onResume → onPause → onStop → onDestroy + onRestart を通ります。各状態は、開発者に状態の保存、リソースの解放、または復帰の準備のための機会を提供します。Appleドキュメントによると、ライフサイクルイベントを無視することは、アプリの最小化時のクラッシュの40 %の原因です。IT Sectrでは、すべてのプロジェクトにおいてAndroidのProcessLifecycleOwnerとiOSのAppDelegateパターンを必須標準として実装しました — これにより、バックグラウンド関連のバグが60 %削減されました。

重要なポイント

  • App Lifecycle — 起動から終了までのアプリ状態のセット。各状態には特定の開発者アクションがあります。
  • AppDelegate — ライフサイクル処理のためのiOSの中核クラス:didFinishLaunching、didEnterBackground、willEnterForeground。
  • SceneDelegate — 個別のシーン用のデリゲート(iOS 13+)、マルチウィンドウアプリケーションの各ウィンドウのライフサイクルを管理。
  • ProcessLifecycleOwner — AndroidX LifecycleのAndroidコンポーネントで、プロセス全体のライフサイクルを追跡。
  • Application.onCreate — Androidアプリケーションの最初のエントリポイントで、すべてのActivityの前に呼ばれます。

App Lifecycleとは?

App Lifecycleは、モバイルアプリケーションのすべての可能な状態とそれらの間の遷移を記述する有限状態マシンです。各状態は、アプリがコードを実行できるか、UIを表示できるか、リソースを消費できるかを決定します。iOSとAndroidのモデルは似ていますが同一ではありません — 違いはOSアーキテクチャに起因します:iOSは厳格なメモリ制御(suspended状態)を使用し、AndroidはonSaveInstanceStateを通じた柔軟なプロセス管理を使用します。

iOSでは、ライフサイクルはフォアグラウンド/バックグラウンドに強く結びついています:アプリはアクティブかサスペンドのいずれかです。Androidでは、ライフサイクルはより細かく — Activity/ウィンドウは6つ以上の状態を経由し、プロセス自体がProcessLifecycleOwnerを通じて追加のライフサイクルを持ちます。現代のアプリケーション(2024年以降)は、ライフサイクルベースのアーキテクチャパターンをますます使用しています:SwiftUI Lifecycle(iOS 16+)は.scenePhase環境を通じて、Compose LifecycleはLifecycleEventObserverを通じて。これらのパターンは自動的にコンテキスト切り替えを処理し、メモリリークを防ぎます。Googleによると、Androidでの適切なライフサイクル処理は、バックグラウンド作業中のメモリ消費を30~40 %削減します。

iOSのライフサイクル:AppDelegateとSceneDelegate

iOSでは、アプリのライフサイクルはUIApplicationDelegateクラス(AppDelegate)を通じて管理されます。主なメソッド:application(_:didFinishLaunchingWithOptions:) — 初回起動時の初期化;applicationDidBecomeActive — アプリが表示され、操作可能;applicationWillResignActive — 非アクティブ状態への遷移(着信、通知シェードを閉じる);applicationDidEnterBackground — アプリが非表示、データ保存に約5秒;applicationWillEnterForeground — バックグラウンドから戻る;applicationWillTerminate — 終了(サスペンドがない古いアプリのみ呼ばれます)。

iOS 13以降、AppleはiPadとmacOS CatalystでのマルチウィンドウアプリケーションをサポートするためにSceneDelegate(UISceneDelegate)を導入しました。SceneDelegateは各シーン(ウィンドウ)の個別のライフサイクルを管理します:scene(_:willConnectTo:options:) — シーン作成;sceneDidBecomeActive — シーンがアクティブ;sceneWillResignActive — シーンがフォーカスを失う;sceneDidEnterBackground — シーンが非表示。AppDelegateはグローバルイベント(データ読み込み、プッシュ通知)を処理し、SceneDelegateは各ウィンドウのUI状態を処理します。SwiftUIでは、ライフサイクルは@Environment(\.scenePhase):.active、.inactive、.backgroundの環境値を介して処理されます — これによりSwiftUIとUIKitアプリケーションの両方に統一されたAPIが提供されます。

Androidのライフサイクル:ApplicationとProcessLifecycleOwner

Androidでは、ライフサイクルはApplicationクラスから始まります — すべてのActivityより前に作成されるシングルトンです。Application.onCreate()メソッドは最初のエントリポイントで、グローバル初期化(Analytics、DI、Crash Reporting)に使用されます。その後、Activityが次の順序で起動します:onCreate() → onStart() → onResume()。最小化時:onPause() → onStop() → onSaveInstanceState()。破棄時:onDestroy()。復帰時:onRestart() → onStart() → onResume()。

ProcessLifecycleOwner(AndroidX Lifecycle 2.2+)は、個別のActivityではなくプロセス全体のライフサイクルを追跡します。2つの状態を提供します:ON_RESUME(アプリがフォアグラウンド)とON_STOP(アプリが非表示)。ProcessLifecycleOwnerはプロセスレベルで「アプリがいつバックグラウンドに移行したか」の問題を解決します — これはSDK、ライブラリ、モジュラーアプリケーションにとって重要です。Jetpack Composeでは、ライフサイクルはLifecycleEventObserverとcollectAsStateWithLifecycleを通じて管理され、バックグラウンドモードで自動的にデータ収集を中断します。Android 14(API 34)はService.onTimeoutを介したフォアグラウンドサービスのライフサイクル通知を追加しました — サービスは6時間以内に完了する必要があり、そうしないとシステムが強制的に停止します。

iOSとAndroidのライフサイクル比較

iOS Android 説明
Not Running アプリが起動していない
didFinishLaunching Application.onCreate 起動時の最初の初期化
Active onResume アプリが表示され入力を受け付けている
Inactive onPause 一時的なフォーカス喪失(着信、通知シェード)
Background onStop アプリが非表示、コードは実行可能
Suspended コードは実行されず、メモリは予約済み
Will Terminate onDestroy アプリが終了中

主な違い:iOSはバックグラウンドに入ってから5〜10秒後にアプリを強制的にSuspended(コード実行停止)に移行します。Androidはより長い期間のバックグラウンド作業(サービス、WorkManager)を許可しますが、Dozeモード(Android 6+)とバックグラウンド制限(Android 12+)の制限があります。AndroidのProcessLifecycleOwnerはiOSのUIApplicationDidEnterBackgroundNotificationに相当し、フォーカスを失った後だけでなく、バックグラウンドへの任意の遷移時に発火する点が異なります。

コード例

iOS:ライフサイクルメソッドを持つAppDelegate

すべてのライフサイクル状態を処理する基本的なAppDelegate実装。バックグラウンド移行時のデータ保存と復帰時のUI更新。

swift
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        Analytics.shared.initialize()
        return true
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        NotificationCenter.default.post(name: .appDidBecomeActive, object: nil)
    }

    func applicationWillResignActive(_ application: UIApplication) {
        NotificationCenter.default.post(name: .appWillResignActive, object: nil)
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        CoreDataManager.shared.saveContext()
        UserDefaults.standard.synchronize()
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        NetworkManager.shared.refreshSession()
    }
}

AppDelegateはライフサイクルの中核ポイントです。applicationDidEnterBackgroundは重要なメソッドです:iOSは保存に約5秒を与えます。applicationDidBecomeActive — UIを更新し、アニメーションを再開します。SceneDelegate(iOS 13+)では、ライフサイクルロジックはシーン全体に分散されます:sceneDidBecomeActive / sceneDidEnterBackgroundが個々のウィンドウを管理します。

iOS:SceneDelegate(iOS 13+)

マルチウィンドウiPadアプリケーション用のSceneDelegate。各シーンには、他のウィンドウから独立した独自のライフサイクルがあります。

swift
import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(
        _ scene: UIScene,
        willConnectTo session: UISceneSession,
        options connectionOptions: UIScene.ConnectionOptions
    ) {
        guard let windowScene = (scene as? UIWindowScene) else { return }
        window = UIWindow(windowScene: windowScene)
        window?.rootViewController = ViewController()
        window?.makeKeyAndVisible()
    }

    func sceneDidBecomeActive(_ scene: UIScene) {
        PlayerManager.shared.resume()
    }

    func sceneDidEnterBackground(_ scene: UIScene) {
        PlayerManager.shared.pause()
        CoreDataManager.shared.saveContext()
    }

    func sceneDidDisconnect(_ scene: UIScene) {
        PlayerManager.shared.cleanup()
    }
}

SceneDelegateは個別のシーンのライフサイクルを管理します。sceneDidBecomeActive / sceneDidEnterBackgroundは、特定のウィンドウのAppDelegateメソッドに相当します。sceneDidDisconnectはシーンが閉じられたときに呼ばれます(ユーザーがiPadでウィンドウを閉じました)。iOS 12以下との互換性のために、AppDelegateはSceneDelegateのロジックを複製する必要があります。iOS 17+では、@Observableを使用してscenePhaseに基づいてタスクを自動的に一時停止/再開できます。

Android:ProcessLifecycleOwnerを使用したApplication

ProcessLifecycleOwnerは、アプリがプロセスレベルでフォアグラウンド/バックグラウンドのどちらにあるかを追跡します。これはグローバルなライフサイクル管理に最適なアプローチです。

kotlin
import android.app.Application
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent

class MainApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifecycleObserver())
    }
}

class AppLifecycleObserver : LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onEnterForeground() {
        Analytics.shared.onForeground()
        NetworkMonitor.shared.start()
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onEnterBackground() {
        Analytics.shared.onBackground()
        NetworkMonitor.shared.stop()
    }
}

ProcessLifecycleOwnerは、アプリケーションレベルでバックグラウンドへの移行を追跡する唯一の正しい方法です。ON_STARTはアプリが表示されたとき(フォアグラウンド)に発火し、ON_STOP — 完全に非表示になったとき(バックグラウンド)に発火します。Activityのライフサイクルとは異なり、ProcessLifecycleOwnerは特定の画面に結びつきません。Jetpack Composeでは、手動監視の代わりにLifecycleResumeEffectまたはcollectAsStateWithLifecycleを使用してください。

Android:ViewModelを使用したActivityのライフサイクル

ViewModel + Lifecycleは、ライフサイクル管理のための正しいAndroidアーキテクチャです。ViewModelはonDestroyで自動的にクリーンアップされ、リークを防ぎます。

kotlin
import androidx.lifecycle.ViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData

class TimerViewModel : ViewModel() {

    private val _time = MutableLiveData<Long>()
    val time: LiveData<Long> = _time

    private var startTime = System.currentTimeMillis()

    init {
        updateTime()
    }

    private fun updateTime() {
        _time.value = System.currentTimeMillis() - startTime
    }

    override fun onCleared() {
        super.onCleared()
        Logger.d("ViewModel cleared — リソースを解放")
    }
}

// Activity内
class TimerActivity : AppCompatActivity() {

    private val viewModel: TimerViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Logger.d("Activity created")
    }

    override fun onResume() {
        super.onResume()
        viewModel.time.observe(this) { Logger.d("Time: $it") }
    }

    override fun onPause() {
        super.onPause()
        Logger.d("Activity paused — アニメーションを一時停止")
    }

    override fun onDestroy() {
        super.onDestroy()
        Logger.d("Activity destroyed — クリーンアップ")
    }
}

ViewModelは画面の回転を生き残り、Activityのfinish()時にのみ破棄されます。onCleared()はリソースの解放とストリームの購読解除のための場所です。LiveDataはonPauseで自動的に監視を一時停止し、onResumeで再開します — これによりバックグラウンド作業中のリークやクラッシュから保護されます。Composeでは、同じ目的でcollectAsStateWithLifecycle()を使用してください。

よくある質問

ユーザーがiOSアプリを最小化するとどうなりますか?

最小化すると、アプリはアクティブから非アクティブ(一時的に)、次にバックグラウンドに移行します。数秒後、システムはアプリをsuspended(サスペンド)に移行する可能性があります — コードは実行されず、メモリは予約されます。メモリが不足すると、システムはサスペンドされたアプリを終了します(willTerminateは呼ばれません)。applicationDidEnterBackgroundでデータを保存してください — これが保存のための最後の保証されたポイントです。

すべてのApp Lifecycle状態を処理する必要がありますか?

最低限必須:applicationDidEnterBackground — ユーザーデータを保存;applicationWillEnterForeground — UIを更新;AndroidのonPause — アニメーション/センサーを一時停止。ProcessLifecycleOwnerは処理を簡素化します:onResume — onPause(フォアグラウンド)、onStart — onStop(可視性)。必要に応じて他の状態を処理してください — すべての状態がすべてのアプリケーションにとって重要というわけではありません。

SceneDelegateとAppDelegateの違いは?

AppDelegateはアプリケーション全体のグローバルデリゲートです(起動、バックグラウンド移行)。SceneDelegate(iOS 13+)は個別のウィンドウ(シーン)のライフサイクルを管理します — マルチウィンドウiPadアプリケーションでは、各シーンに独自のライフサイクルがあります。iOS 12以下では、すべてのライフサイクルはAppDelegateを通じて処理されます。iPadOS 16+では、Stage ManagerにSceneDelegateが必要です。

AndroidのProcessLifecycleOwnerとは?

ProcessLifecycleOwnerは、AndroidX Lifecycleのコンポーネントで、個別のActivityではなくアプリケーション全体(プロセス)のライフサイクルを追跡します。2つの主要なイベントを提供します:ON_RESUME(アプリがフォアグラウンド)とON_STOP(アプリがバックグラウンド)。SDK、アナリティクス、ネットワークモニターの初期化/クリーンアップに使用されます — 現在の画面に関係なく、アプリのバックグラウンド移行に反応する必要があるものすべてに使用します。

Jetpack Composeでライフサイクルを処理するには?

Jetpack Composeでは、LocalLifecycleOwner.current.lifecycleまたはcollectAsStateWithLifecycle()関数を介してLifecycleEventObserverを使用します。Compose画面では、LifecycleResumeEffectを使用します — DisposableEffectと同様に、onResumeで実行されonPauseでクリーンアップされます。lifecycleScope.launchWhenResumed — バックグラウンドで自動的に一時停止されるコルーチンです。

まとめ

  • App Lifecycleは、リソース管理、データ永続化、安定性を決定するアプリ状態の有限状態マシンです。
  • iOS AppDelegate(applicationDidEnterBackground)は、5秒以内のバックグラウンド移行時のデータ保存に重要なメソッドです。
  • iOS SceneDelegate(iOS 13+)は各シーンのライフサイクルを個別に管理 — マルチウィンドウiPadアプリケーションに必須。
  • Android ProcessLifecycleOwnerは、SDKの初期化/クリーンアップのためのグローバルプロセスライフサイクル監視機能です。
  • AndroidのViewModelは画面回転を生き残り、Activity終了時にクリーンアップ — メモリリークを防止。
  • SwiftUI @Environment(\.scenePhase)はSwiftUIのライフサイクルに統一APIを提供(active、inactive、background)。
  • 適切なライフサイクル処理によりメモリ消費が30〜40%削減され、バックグラウンド作業中のクラッシュの40%を防止します。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください