App Lifecycle: trạng thái ứng dụng trong iOS và Android là gì

Tác giả: IT Sectr Đã đăng: 2026-03-02 Thời gian đọc: 8 phút
App Lifecycle (vòng đời ứng dụng) là chuỗi các trạng thái mà một ứng dụng di động trải qua từ khi khởi động đến khi kết thúc. Hiểu về vòng đời là rất quan trọng để quản lý tài nguyên, lưu trữ dữ liệu và đảm bảo tính ổn định. Trong iOS, ứng dụng trải qua các trạng thái: Not Running → Active → Inactive → Background → Suspended. Trong Android — qua onCreate → onStart → onResume → onPause → onStop → onDestroy + onRestart. Mỗi trạng thái cho nhà phát triển một cơ hội để lưu trạng thái, giải phóng tài nguyên hoặc chuẩn bị cho việc quay lại. Theo Tài liệu Apple, việc bỏ qua các sự kiện vòng đời là nguyên nhân của 40 % sự cố khi thu nhỏ ứng dụng. Tại IT Sectr, chúng tôi đã triển khai ProcessLifecycleOwner trong Android và mẫu AppDelegate trong iOS như các tiêu chuẩn bắt buộc cho tất cả dự án — điều này đã giảm 60 % lỗi liên quan đến nền.

Những điểm chính

  • App Lifecycle — tập hợp các trạng thái ứng dụng từ khi khởi động đến khi kết thúc, mỗi trạng thái có hành động cụ thể của nhà phát triển.
  • AppDelegate — lớp trung tâm của iOS để xử lý vòng đời: didFinishLaunching, didEnterBackground, willEnterForeground.
  • SceneDelegate — đại biểu cho các cảnh riêng lẻ (iOS 13+), quản lý vòng đời của từng cửa sổ trong ứng dụng đa cửa sổ.
  • ProcessLifecycleOwner — thành phần Android từ AndroidX Lifecycle theo dõi vòng đời của toàn bộ tiến trình.
  • Application.onCreate — điểm vào đầu tiên của ứng dụng Android, được gọi trước bất kỳ Activity nào.

App Lifecycle là gì?

App Lifecycle là một máy trạng thái hữu hạn mô tả tất cả các trạng thái có thể của một ứng dụng di động và sự chuyển đổi giữa chúng. Mỗi trạng thái xác định liệu ứng dụng có thể thực thi mã, hiển thị giao diện người dùng và tiêu thụ tài nguyên hay không. iOS và Android có các mô hình tương tự nhưng không giống hệt nhau — sự khác biệt xuất phát từ kiến trúc hệ điều hành: iOS sử dụng kiểm soát bộ nhớ nghiêm ngặt (trạng thái suspended), trong khi Android sử dụng quản lý tiến trình linh hoạt thông qua onSaveInstanceState.

Trong iOS, vòng đời gắn chặt với tiền cảnh/hậu cảnh: ứng dụng hoặc đang hoạt động hoặc bị tạm ngưng. Trong Android, vòng đời chi tiết hơn — một Activity/Cửa sổ trải qua 6+ trạng thái, và bản thân tiến trình có một vòng đời bổ sung thông qua ProcessLifecycleOwner. Các ứng dụng hiện đại (từ năm 2024) ngày càng sử dụng các mẫu kiến trúc dựa trên vòng đời: SwiftUI Lifecycle (iOS 16+) thông qua môi trường .scenePhase, Compose Lifecycle thông qua LifecycleEventObserver. Các mẫu này tự động xử lý chuyển đổi ngữ cảnh và ngăn rò rỉ bộ nhớ. Theo Google, xử lý vòng đời đúng cách trong Android giảm mức tiêu thụ bộ nhớ 30–40 % khi làm việc trong nền.

Vòng đời iOS: AppDelegate và SceneDelegate

Trong iOS, vòng đời ứng dụng được quản lý thông qua lớp UIApplicationDelegate (AppDelegate). Các phương thức chính: application(_:didFinishLaunchingWithOptions:) — khởi tạo lần đầu tiên; applicationDidBecomeActive — ứng dụng hiển thị và sẵn sàng tương tác; applicationWillResignActive — chuyển sang trạng thái không hoạt động (cuộc gọi đến, đóng bảng thông báo); applicationDidEnterBackground — ứng dụng bị ẩn, ~5 giây để lưu dữ liệu; applicationWillEnterForeground — quay lại từ nền; applicationWillTerminate — kết thúc (chỉ được gọi cho ứng dụng cũ không có suspended).

Bắt đầu từ iOS 13, Apple đã giới thiệu SceneDelegate (UISceneDelegate) để hỗ trợ các ứng dụng đa cửa sổ trên iPad và macOS Catalyst. SceneDelegate quản lý vòng đời của từng cảnh (cửa sổ) riêng lẻ: scene(_:willConnectTo:options:) — tạo cảnh; sceneDidBecomeActive — cảnh hoạt động; sceneWillResignActive — cảnh mất tiêu điểm; sceneDidEnterBackground — cảnh bị ẩn. AppDelegate xử lý các sự kiện toàn cầu (tải dữ liệu, thông báo đẩy), trong khi SceneDelegate xử lý trạng thái giao diện người dùng của từng cửa sổ. Trong SwiftUI, vòng đời được xử lý thông qua giá trị môi trường @Environment(\.scenePhase): .active, .inactive, .background — điều này cung cấp một API thống nhất cho cả ứng dụng SwiftUI và UIKit.

Vòng đời Android: Application và ProcessLifecycleOwner

Trong Android, vòng đời bắt đầu với lớp Application — một singleton được tạo trước bất kỳ Activity nào. Phương thức Application.onCreate() là điểm vào đầu tiên, được sử dụng để khởi tạo toàn cầu (Analytics, DI, Crash Reporting). Sau đó, Activity được khởi chạy với trình tự: onCreate() → onStart() → onResume(). Khi thu nhỏ: onPause() → onStop() → onSaveInstanceState(). Khi bị hủy: onDestroy(). Khi quay lại: onRestart() → onStart() → onResume().

ProcessLifecycleOwner (từ AndroidX Lifecycle 2.2+) theo dõi vòng đời của toàn bộ tiến trình, không phải một Activity riêng lẻ. Nó cung cấp hai trạng thái: ON_RESUME (ứng dụng ở tiền cảnh) và ON_STOP (ứng dụng bị ẩn). ProcessLifecycleOwner giải quyết vấn đề «khi nào ứng dụng vào nền» ở cấp độ tiến trình — điều này rất quan trọng cho SDK, thư viện và ứng dụng mô-đun. Trong Jetpack Compose, vòng đời được quản lý thông qua LifecycleEventObserver và collectAsStateWithLifecycle, tự động tạm ngưng thu thập dữ liệu ở chế độ nền. Android 14 (API 34) đã thêm thông báo vòng đời dịch vụ tiền cảnh qua Service.onTimeout — dịch vụ phải hoàn thành trong vòng 6 giờ, nếu không hệ thống sẽ buộc dừng nó.

So sánh vòng đời iOS và Android

iOS Android Mô tả
Not Running Ứng dụng chưa được khởi động
didFinishLaunching Application.onCreate Khởi tạo đầu tiên khi khởi động
Active onResume Ứng dụng hiển thị và đang nhận đầu vào
Inactive onPause Mất tiêu điểm tạm thời (cuộc gọi, bảng thông báo)
Background onStop Ứng dụng bị ẩn, mã có thể đang thực thi
Suspended Mã không thực thi, bộ nhớ được dự trữ
Will Terminate onDestroy Ứng dụng đang kết thúc

Sự khác biệt chính: iOS buộc ứng dụng chuyển sang Suspended (mã ngừng thực thi) 5-10 giây sau khi vào nền. Android cho phép làm việc trong nền (dịch vụ, WorkManager) trong thời gian dài hơn, nhưng với các giới hạn của Chế độ Doze (Android 6+) và hạn chế nền (Android 12+). ProcessLifecycleOwner trong Android tương đương với UIApplicationDidEnterBackgroundNotification trong iOS, với điểm khác biệt là nó kích hoạt khi bất kỳ chuyển đổi nào vào nền, không chỉ sau khi mất tiêu điểm.

Ví dụ mã

iOS: AppDelegate với các phương thức vòng đời

Triển khai AppDelegate cơ bản xử lý tất cả trạng thái vòng đời. Lưu dữ liệu khi chuyển sang nền và cập nhật giao diện người dùng khi quay lại.

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 là điểm trung tâm của vòng đời. applicationDidEnterBackground là phương thức quan trọng: iOS cho ~5 giây để lưu. applicationDidBecomeActive — cập nhật giao diện người dùng, khởi động lại hoạt ảnh. Đối với SceneDelegate (iOS 13+), logic vòng đời được phân phối qua các cảnh: sceneDidBecomeActive / sceneDidEnterBackground quản lý các cửa sổ riêng lẻ.

iOS: SceneDelegate (iOS 13+)

SceneDelegate cho ứng dụng iPad đa cửa sổ. Mỗi cảnh có vòng đời riêng, độc lập với các cửa sổ khác.

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 quản lý vòng đời của một cảnh riêng lẻ. sceneDidBecomeActive / sceneDidEnterBackground tương đương với các phương thức AppDelegate cho một cửa sổ cụ thể. sceneDidDisconnect được gọi khi một cảnh đóng (người dùng đã đóng cửa sổ trên iPad). Để tương thích với iOS 12 trở xuống, AppDelegate phải sao chép logic SceneDelegate. Trong iOS 17+, bạn có thể sử dụng @Observable để tự động tạm dừng/tiếp tục tác vụ dựa trên scenePhase.

Android: Application với ProcessLifecycleOwner

ProcessLifecycleOwner theo dõi khi ứng dụng ở tiền cảnh/hậu cảnh ở cấp độ tiến trình. Đây là cách tiếp cận tối ưu để quản lý vòng đời toàn cầu.

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 là cách duy nhất chính xác để theo dõi chuyển đổi sang nền ở cấp độ ứng dụng. ON_START kích hoạt khi ứng dụng hiển thị (tiền cảnh), ON_STOP — khi bị ẩn hoàn toàn (hậu cảnh). Không giống như vòng đời Activity, ProcessLifecycleOwner không gắn với một màn hình cụ thể. Đối với Jetpack Compose, hãy sử dụng LifecycleResumeEffect hoặc collectAsStateWithLifecycle thay vì quan sát thủ công.

Android: Vòng đời Activity với ViewModel

ViewModel + Lifecycle là kiến trúc Android chính xác để quản lý vòng đời. ViewModel tự động được dọn dẹp khi onDestroy, ngăn rò rỉ.

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 — giải phóng tài nguyên")
    }
}

// Trong 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 — tạm dừng hoạt ảnh")
    }

    override fun onDestroy() {
        super.onDestroy()
        Logger.d("Activity destroyed — dọn dẹp")
    }
}

ViewModel tồn tại qua xoay màn hình và chỉ bị hủy khi Activity kết thúc. onCleared() là nơi giải phóng tài nguyên và hủy đăng ký luồng. LiveData tự động tạm dừng quan sát khi onPause và tiếp tục khi onResume — điều này cung cấp bảo vệ chống rò rỉ và sự cố khi làm việc trong nền. Trong Compose, hãy sử dụng collectAsStateWithLifecycle() cho mục đích tương tự.

Câu hỏi thường gặp

Điều gì xảy ra khi người dùng thu nhỏ ứng dụng iOS?

Khi thu nhỏ, ứng dụng chuyển từ hoạt động sang không hoạt động (ngắn), sau đó vào nền. Sau vài giây, hệ thống có thể chuyển nó sang suspended — mã ngừng thực thi, bộ nhớ được dự trữ. Khi thiếu bộ nhớ, hệ thống kết thúc ứng dụng bị tạm ngưng (willTerminate không được gọi). Lưu dữ liệu của bạn trong applicationDidEnterBackground — đây là điểm đảm bảo cuối cùng để lưu.

Tôi có cần xử lý tất cả trạng thái App Lifecycle không?

Tối thiểu bắt buộc: applicationDidEnterBackground — lưu dữ liệu người dùng; applicationWillEnterForeground — cập nhật giao diện người dùng; trong Android onPause — tạm dừng hoạt ảnh/cảm biến. ProcessLifecycleOwner đơn giản hóa việc xử lý: onResume — onPause cho tiền cảnh, onStart — onStop cho khả năng hiển thị. Xử lý các trạng thái khác khi cần — không phải tất cả trạng thái đều quan trọng cho mọi ứng dụng.

SceneDelegate khác AppDelegate như thế nào?

AppDelegate là đại biểu toàn cầu của toàn bộ ứng dụng (khởi động, chuyển đổi nền). SceneDelegate (iOS 13+) quản lý vòng đời của một cửa sổ riêng lẻ (cảnh) — trong ứng dụng iPad đa cửa sổ, mỗi cảnh có vòng đời riêng. Đối với iOS 12 trở xuống, tất cả vòng đời được xử lý qua AppDelegate. Với iPadOS 16+, SceneDelegate là bắt buộc cho Stage Manager.

ProcessLifecycleOwner trong Android là gì?

ProcessLifecycleOwner là một thành phần từ AndroidX Lifecycle theo dõi vòng đời của toàn bộ ứng dụng (tiến trình), không phải một Activity riêng lẻ. Nó cung cấp hai sự kiện chính: ON_RESUME (ứng dụng ở tiền cảnh) và ON_STOP (ứng dụng ở hậu cảnh). Nó được sử dụng để khởi tạo/dọn dẹp SDK, phân tích, giám sát mạng — bất cứ thứ gì cần phản ứng với việc ứng dụng chuyển sang nền, bất kể màn hình hiện tại.

Làm thế nào để xử lý vòng đời trong Jetpack Compose?

Trong Jetpack Compose, hãy sử dụng LifecycleEventObserver thông qua LocalLifecycleOwner.current.lifecycle hoặc hàm collectAsStateWithLifecycle(). Đối với màn hình Compose, hãy sử dụng LifecycleResumeEffect — tương tự DisposableEffect, chạy khi onResume và dọn dẹp khi onPause. lifecycleScope.launchWhenResumed — một coroutine tự động tạm ngưng trong nền.

Tổng kết

  • App Lifecycle là một máy trạng thái hữu hạn xác định quản lý tài nguyên, lưu trữ dữ liệu và tính ổn định.
  • iOS AppDelegate (applicationDidEnterBackground) là phương thức quan trọng để lưu dữ liệu khi chuyển sang nền trong vòng 5 giây.
  • iOS SceneDelegate (iOS 13+) quản lý vòng đời của từng cảnh riêng biệt — bắt buộc cho ứng dụng iPad đa cửa sổ.
  • Android ProcessLifecycleOwner là người quan sát vòng đời tiến trình toàn cầu để khởi tạo/dọn dẹp SDK.
  • ViewModel trong Android tồn tại qua xoay màn hình và được dọn dẹp khi Activity kết thúc — ngăn rò rỉ bộ nhớ.
  • SwiftUI @Environment(\.scenePhase) cung cấp API thống nhất cho vòng đời trong SwiftUI (active, inactive, background).
  • Xử lý vòng đời đúng cách giảm mức tiêu thụ bộ nhớ 30-40% và ngăn 40% sự cố khi làm việc trong nền.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm