Active: nó là gì, trạng thái Active trong vòng đời iOS

Tác giả: IT Sectr Đã đăng: 2026-03-03 Thời gian đọc: 10 phút

Active — trạng thái hoạt động của vòng đời ứng dụng iOS, trong đó ứng dụng ở tiền cảnh, nhận sự kiện chạm và tương tác với người dùng. Chúng ta tìm hiểu trạng thái Active hoạt động như thế nào, các phương thức nào của UIApplicationDelegate chịu trách nhiệm cho nó và cách xử lý chính xác các chuyển đổi giữa Active và Inactive trong Swift.

Chính yếu

  • Active — ứng dụng ở tiền cảnh, UIResponder nhận sự kiện chạm, ứng dụng hoàn toàn tương tác được
  • applicationDidBecomeActive — phương thức chính, báo hiệu chuyển sang Active trên iOS
  • ScenePhase.active — tương đương cho SwiftUI, theo dõi qua Environment values
  • Quay lại từ Inactive — sau cuộc gọi, thông báo hoặc Control Center ứng dụng lại trở thành Active
  • Tài nguyên — ở Active ứng dụng có quyền ưu tiên cao nhất về bộ nhớ và CPU

Active: đây là trạng thái gì

Active — trạng thái của vòng đời ứng dụng di động, trong đó nó ở tiền cảnh, hiển thị trên màn hình thiết bị và tương tác tích cực với người dùng. Ở trạng thái này, ứng dụng nhận tất cả các sự kiện chạm, nhấn phím, dữ liệu từ gia tốc kế và con quay hồi chuyển, cũng như có toàn quyền truy cập vào bộ xử lý đồ họa để kết xuất giao diện.

Trên iOS, trạng thái Active là một phần của mô hình vòng đời năm trạng thái: Not Running → Inactive → Active → Inactive → Background → Suspended → Not Running. Trên Android, tương tự là trạng thái Activity sau khi gọi onResume, khi Activity ở đỉnh ngăn xếp và nhận đầu vào từ người dùng. Active là trạng thái duy nhất UI hoàn toàn tương tác được và phản hồi với cử chỉ, cuộn, nhấn và hoạt ảnh.

Hệ thống cung cấp cho ứng dụng ở Active quyền ưu tiên tối đa về CPU và RAM. Điều này có nghĩa là hệ thống sẽ không kết thúc ứng dụng như vậy khi thiếu tài nguyên — trước tiên các tiến trình nền và bị tạm dừng sẽ được giải phóng. Tuy nhiên, ứng dụng phải sử dụng tài nguyên hiệu quả để không làm hao pin và gây ra tình trạng throttling CPU.

Đối với người dùng, Active là trạng thái làm việc bình thường với ứng dụng. Người dùng nhìn thấy giao diện, có thể nhấn nút, điền biểu mẫu, cuộn bảng tin. Bất kỳ sự gián đoạn nào của trạng thái này (cuộc gọi, thông báo, vuốt lên để mở Control Center) đều chuyển ứng dụng sang Inactive, sau đó nó có thể quay lại Active hoặc vào Background.

Hệ thống xác định ứng dụng Active như thế nào

iOS sử dụng UIApplicationMain để quản lý trạng thái. Khi chuyển sang Active, hệ thống gọi applicationDidBecomeActive. Đối với SwiftUI, cơ chế tương tự là quan sát scenePhase qua Environment. Android sử dụng onResume như chỉ báo hoạt động của Activity ở tiền cảnh. Cả hai cách tiếp cận đều đảm bảo rằng ứng dụng nhận được thông báo về sự thay đổi trạng thái và có thể điều chỉnh hành vi của mình.

Nền tảngPhương thức/Sự kiệnSwift (UIKit)SwiftUIAndroid (Kotlin)
iOSChuyển sang ActiveapplicationDidBecomeActivescenePhase == .active
iOSRời khỏi ActiveapplicationWillResignActivescenePhase == .inactive
AndroidChuyển sang ActiveonResume()
AndroidRời khỏi ActiveonPause()

Active trong iOS: Swift, UIKit và SwiftUI

Trong iOS, trạng thái Active được xử lý qua UIApplicationDelegate. Phương thức chính — applicationDidBecomeActive(_:). Nó được gọi khi khởi chạy ứng dụng lần đầu và khi quay lại từ Inactive. Phương thức này là nơi lý tưởng để tiếp tục các tác vụ đã bị tạm dừng khi vào Inactive: bắt đầu hoạt ảnh, tiếp tục bộ đếm thời gian, khởi động lại cảm biến, kiểm tra cập nhật dữ liệu trên máy chủ.

UIKit: AppDelegate và SceneDelegate

Từ iOS 13, Apple đã giới thiệu UISceneDelegate để hỗ trợ nhiều cửa sổ trên iPad. Trong trường hợp này, applicationDidBecomeActive được thay thế bằng sceneDidBecomeActive cho từng scene riêng lẻ. Các ứng dụng chỉ hỗ trợ một màn hình có thể tiếp tục sử dụng UIApplicationDelegate. Cả hai cách tiếp cận đều được gọi tại thời điểm ứng dụng hoặc scene trở nên hoạt động.

swift
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    // Ứng dụng đã hoạt động — tiếp tục tác vụ
    func applicationDidBecomeActive(_ application: UIApplication) {
        resumeAnimations()
        restartTimers()
        refreshDataIfNeeded()
        startObservingSensors()
    }

    // Ứng dụng mất hoạt động — tạm dừng
    func applicationWillResignActive(_ application: UIApplication) {
        pauseAnimations()
        stopTimers()
        saveDraftData()
    }

    private func resumeAnimations() {
        UIView.animate(withDuration: 0.3) {
            // Tiếp tục hoạt ảnh UI
        }
    }

    private func refreshDataIfNeeded() {
        let lastRefresh = UserDefaults.standard.object(forKey: "lastRefresh") as? Date ?? .distantPast
        if Date().timeIntervalSince(lastRefresh) > 300 {
            fetchDataFromServer()
        }
    }
}

Mã cho thấy cách xử lý Active chính xác trong UIKit. applicationDidBecomeActive tiếp tục hoạt ảnh, bộ đếm thời gian và kiểm tra xem có cần cập nhật dữ liệu không. applicationWillResignActive tạm dừng mọi thứ có thể tiêu tốn tài nguyên và lưu bản nháp. Cặp phương thức như vậy đảm bảo ứng dụng phản ứng chính xác với sự thay đổi trạng thái.

SwiftUI: scenePhase

Trong SwiftUI không có AppDelegate — quản lý trạng thái diễn ra qua Environment<ScenePhase>. Giá trị .active được đặt khi scene ở tiền cảnh và có thể tương tác. SwiftUI tự động khởi động lại hoạt ảnh và cập nhật khi quay lại Active. Nhà phát triển chỉ cần đăng ký onChange để thực hiện các hiệu ứng phụ.

swift
import SwiftUI

@main
struct ActiveDemoApp: App {
    @Environment(\.scenePhase) private var scenePhase

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .onChange(of: scenePhase) { oldPhase, newPhase in
            switch newPhase {
            case .active:
                print("Scene đã hoạt động")
                resumeWork()
            case .inactive:
                print("Scene đã không hoạt động")
                pauseWork()
            case .background:
                print("Scene đã vào nền")
                saveState()
            @unknown default:
                break
            }
        }
    }

    private func resumeWork() {
        // Tiếp tục yêu cầu mạng, hoạt ảnh
    }

    private func pauseWork() {
        // Tạm dừng tác vụ nhạy cảm với thời gian
    }

    private func saveState() {
        // Lưu trạng thái ứng dụng
    }
}

Trong SwiftUI, scenePhase là nguồn chân lý duy nhất về trạng thái ứng dụng. onChange cho phép thực hiện các hành động ở mỗi lần chuyển đổi. Điều quan trọng cần nhớ là scenePhase chỉ khả dụng trên iOS 14+ và trong SwiftUI Lifecycle. Đối với ứng dụng UIKit có màn hình SwiftUI, hãy sử dụng cách tiếp cận với UIApplicationDelegate.

Chuyển đổi sang trạng thái Active

Active đạt được qua nhiều con đường. Đầu tiên và rõ ràng nhất — khởi động nguội: người dùng nhấn vào biểu tượng, ứng dụng chuyển từ Not Running qua Inactive sang Active. Thứ hai — quay lại từ nền: người dùng chuyển về ứng dụng qua App Switcher, ứng dụng đi qua Inactive và trở thành Active. Thứ ba — quay lại từ gián đoạn tạm thời: người dùng kết thúc cuộc gọi, đóng Control Center hoặc trả lời thông báo — ứng dụng quay lại từ Inactive sang Active.

Chuỗi chuyển đổi sang Active

Not Running → Inactive → Active — khởi động nguội. Background → Inactive → Active — quay lại từ nền. Inactive → Active — quay lại từ gián đoạn tạm thời. Trong mỗi trường hợp, applicationDidBecomeActive được gọi, nhưng ngữ cảnh có thể khác nhau. Khi khởi động nguội, trước Active gọi didFinishLaunchingWithOptions, khi quay lại từ nền — willEnterForeground. Nhà phát triển có thể sử dụng những khác biệt này để chọn chiến lược khôi phục trạng thái.

Kịch bảnĐường dẫn chuyển đổiCallback iOSCallback Android
Khởi động nguộiNot Running → ActivedidFinishLaunching → didBecomeActiveonCreate → onStart → onResume
Quay lại từ nềnBackground → ActivewillEnterForeground → didBecomeActiveonRestart → onStart → onResume
Quay lại từ SuspendedSuspended → ActivewillEnterForeground → didBecomeActiveonRestart → onStart → onResume
Sau gián đoạnInactive → ActivedidBecomeActiveonResume

Lưu ý quan trọng: khi quay lại từ Suspended, iOS không gọi didFinishLaunchingWithOptions vì ứng dụng đã được tải vào bộ nhớ. Điều này có nghĩa là mã khởi tạo đặt trong phương thức này không được thực thi lại. Các nhà phát triển thường quên điều này và chuyển logic quan trọng sang applicationWillEnterForeground hoặc applicationDidBecomeActive cho cả hai kịch bản.

Active trong Android: vòng đời Activity

Trong Android, tương tự của Active là trạng thái Activity sau khi gọi onResume(). Activity được coi là hoạt động khi nó ở tiền cảnh và nhận đầu vào từ người dùng. Trạng thái này tương ứng với đỉnh của ngăn xếp Activity. Nếu một Activity khác xuất hiện phía trên (thậm chí một phần), Activity hiện tại chuyển sang trạng thái onPause — tương tự iOS Inactive.

Sự khác biệt chính của Android — nhiều Activity có thể hoạt động đồng thời trong chế độ multi-window (split screen, freeform). Trong trường hợp này, Activity mà người dùng tương tác được coi là hoạt động, còn Activity bên cạnh bị tạm dừng (onPause). iOS không hỗ trợ multi-window trên iPhone, chỉ trên iPad qua UIScene.

kotlin
class MainActivity : AppCompatActivity() {

    override fun onResume() {
        super.onResume()
        // Ứng dụng đã hoạt động — tiếp tục tác vụ
        resumeCameraPreview()
        startLocationUpdates()
        activateSensors()
    }

    override fun onPause() {
        super.onPause()
        // Ứng dụng mất hoạt động — giải phóng tài nguyên
        releaseCamera()
        stopLocationUpdates()
        deactivateSensors()
    }

    private fun resumeCameraPreview() {
        // Bắt đầu xem trước camera (cần quyền)
        cameraProvider?.unbindAll()
        cameraProvider?.bindToLifecycle(
            this,
            cameraSelector,
            preview,
            imageAnalyzer
        )
    }

    private fun startLocationUpdates() {
        val locationRequest = LocationRequest.Builder(
            Priority.PRIORITY_HIGH_ACCURACY, 5000
        ).build()
        locationClient.requestLocationUpdates(
            locationRequest,
            locationCallback,
            Looper.getMainLooper()
        )
    }
}

Mã cho thấy cách xử lý Active trong Android qua onResume/onPause. onResume tiếp tục làm việc với camera, định vị địa lý và cảm biến — những tài nguyên chỉ nên hoạt động khi ứng dụng hiển thị cho người dùng. onPause giải phóng các tài nguyên này để không hao pin. CameraX lifecycle-aware API tự động tạm dừng xem trước khi onPause.

Phương pháp hay nhất xử lý Active

Quy tắc đầu tiên — không thực hiện các thao tác nặng trong applicationDidBecomeActive hoặc onResume. Tải dữ liệu, phân tích cú pháp JSON, làm việc với cơ sở dữ liệu — tất cả đều phải bất đồng bộ và không chặn luồng chính. Sử dụng GCD (DispatchQueue) trong iOS và Coroutines trong Kotlin cho các tác vụ nền. Luồng chính chỉ nên cập nhật UI và khởi chạy các thao tác bất đồng bộ.

Quy tắc thứ hai — đồng bộ hóa trạng thái mỗi khi quay lại Active. Người dùng có thể đã thay đổi cài đặt trong ứng dụng hệ thống, nhận thông báo push hoặc cập nhật dữ liệu trong ứng dụng khác. Kiểm tra tính hợp lệ của bộ nhớ đệm khi chuyển sang Active — dữ liệu có thể đã cũ trong thời gian người dùng vắng mặt.

Quy tắc thứ ba — không phụ thuộc vào Active như trạng thái duy nhất. Ứng dụng có thể bỏ qua Active và chuyển trực tiếp từ Not Running sang Background (nếu khởi chạy ở chế độ nền). Trên iOS, điều này xảy ra khi khởi chạy qua thông báo push với tùy chọn content-available. Trên Android — khi khởi chạy qua BroadcastReceiver. Luôn kiểm tra trạng thái hiện tại trước khi thực hiện thao tác UI.

Quy tắc thứ tư — sử dụng Activity Result API trên Android thay vì onActivityResult. Điều này cho phép xử lý kết quả gọi camera, thư viện ảnh hoặc quyền ngay trong trạng thái Active mà không mất dữ liệu khi tạo lại Activity. Đối với iOS, sử dụng async/await với UIApplication.shared.open cho các hộp thoại hệ thống.

swift
import UIKit

final class ActiveStateManager {
    static let shared = ActiveStateManager()
    private var isActive = false

    func setActive(_ active: Bool) {
        isActive = active
        if active {
            NotificationCenter.default.post(name: .appDidBecomeActive, object: nil)
        }
    }

    func performWhenActive(_ block: @escaping () -> Void) {
        if isActive {
            block()
        } else {
            // Trì hoãn thực thi cho đến khi quay lại Active
            NotificationCenter.default.addObserver(
                forName: .appDidBecomeActive,
                object: nil,
                queue: .main
            ) { _ in
                block()
            }
        }
    }
}

extension Notification.Name {
    static let appDidBecomeActive = Notification.Name("appDidBecomeActive")
}

Mã cho thấy trình quản lý trạng thái Active, cho phép các thành phần khác của ứng dụng kiểm tra trạng thái hoạt động hiện tại. performWhenActive thực thi khối ngay lập tức nếu ứng dụng đang hoạt động hoặc trì hoãn thực thi cho đến khi quay lại Active. Điều này hữu ích cho các dịch vụ cần thực hiện hành động sau khi người dùng quay lại ứng dụng.

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

Bao lâu thì applicationDidBecomeActive được gọi một lần?

Phương thức được gọi mỗi khi ứng dụng chuyển sang trạng thái hoạt động: khi khởi chạy lần đầu, khi quay lại từ nền, sau khi đóng Control Center hoặc Notification Center, sau khi kết thúc cuộc gọi. Trong một phiên bình thường có thể được gọi 5–10 lần tùy thuộc vào hành động của người dùng. Không đặt khởi tạo một lần trong phương thức này.

Active khác Visible trên iOS như thế nào?

Visible — thuật ngữ không chính thức, có nghĩa là ứng dụng hiển thị trên màn hình nhưng có thể không nhận sự kiện (ví dụ: bị che một phần bởi cửa sổ khác trên iPad). Active — trạng thái chính thức, trong đó ứng dụng vừa hiển thị vừa tương tác được. Trên iPhone, ứng dụng Visible luôn là Active, trên iPad có thể xảy ra tình huống Visible + Inactive.

didBecomeActive vs willEnterForeground là gì?

willEnterForeground được gọi khi quay lại từ nền, nhưng ứng dụng chưa hoạt động — nó đang ở Inactive. didBecomeActive được gọi sau khi ứng dụng trở nên hoàn toàn tương tác được. Nếu cần thực hiện hành động trước khi người dùng nhìn thấy giao diện — hãy sử dụng willEnterForeground. Nếu sau khi hiển thị — didBecomeActive.

Ứng dụng có thể Active mà không có UI hiển thị không?

Không. Active có nghĩa là ứng dụng ở tiền cảnh và hiển thị trên màn hình. Không có UI hiển thị, ứng dụng có thể ở Background hoặc Suspended. Ngoại lệ — iPad multi-window, nơi một cửa sổ có thể hoạt động và cửa sổ khác thì không, nhưng cả hai đều hiển thị. VoiceOver và dictation không thay đổi quy tắc này.

Làm thế nào để kiểm tra chuyển đổi sang Active trên trình mô phỏng?

Trên trình mô phỏng iOS, nhấn Cmd+Shift+H để chuyển đến Home Screen (ứng dụng vào Background), sau đó nhấn lại vào biểu tượng ứng dụng. Sử dụng Cmd+L để khóa màn hình (willResignActive) và mở khóa (didBecomeActive). Để kiểm tra Inactive, gọi Control Center (Cmd+Shift+; cho bàn phím macOS) hoặc Notification Center.

Tổng kết

  • Active — trạng thái ứng dụng ở tiền cảnh với toàn quyền truy cập đầu vào người dùng và ưu tiên tài nguyên tối đa
  • iOS UIKit — applicationDidBecomeActive để tiếp tục hoạt ảnh, bộ đếm thời gian và cảm biến
  • SwiftUI — scenePhase .active qua Environment, onChange cho hiệu ứng phụ
  • Android — onResume/onPause như tương tự của Active/Inactive, hỗ trợ multi-window
  • Chuyển đổi — Active đạt được từ Not Running (khởi động nguội), Background và Inactive
  • Tài nguyên — thao tác nặng trong didBecomeActive phải bất đồng bộ, không chặn luồng chính
  • Đồng bộ hóa — kiểm tra tính hợp lệ của bộ nhớ đệm và dữ liệu mỗi khi quay lại Active

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