Inactive — สถานะเปลี่ยนผ่านระหว่าง Active และ Background

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-03-03 เวลาอ่าน: 10 นาที

Inactive — สถานะเปลี่ยนผ่านในวงจรชีวิตแอปพลิเคชันระหว่าง Active และ Background ซึ่งแอปมองเห็นได้บนหน้าจอแต่ไม่รับเหตุการณ์สัมผัส เราอธิบายว่า Inactive เกิดขึ้นบน iOS และ Android ได้อย่างไร เมธอดตัวแทนใดที่รับผิดชอบ และวิธีจัดการกับการขัดจังหวะ — สายเรียกเข้า การแจ้งเตือน และท่าทางระบบ — อย่างถูกต้อง

ประเด็นสำคัญ

  • Inactive — แอปมองเห็นได้บนหน้าจอ แต่ไม่รับเหตุการณ์สัมผัสเนื่องจากการขัดจังหวะของระบบ
  • applicationWillResignActive — เมธอดหลักที่ส่งสัญญาณการเปลี่ยนไปยัง Inactive บน iOS
  • ลักษณะชั่วคราว — Inactive กินเวลาตั้งแต่เสี้ยววินาทีถึงหลายวินาที จากนั้นเปลี่ยนไปยัง Active หรือ Background
  • สาเหตุ — สายเรียกเข้า, Control Center, Notification Center, การแจ้งเตือนระบบ, Apple Pay, Siri
  • SwiftUI — scenePhase .inactive เทียบเท่ากับ Inactive ใน UIKit

Inactive — แก่นแท้ของสถานะเปลี่ยนผ่าน

Inactive เป็นสถานะกลางในวงจรชีวิตของแอปมือถือที่เกิดขึ้นระหว่างการเปลี่ยนระหว่าง Active และ Background ในสถานะนี้ แอปยังคงอยู่เบื้องหน้าและมองเห็นได้สำหรับผู้ใช้ แต่ไม่ได้รับเหตุการณ์สัมผัส การกดแป้นพิมพ์ หรือเหตุการณ์ UI อื่น ๆ ระบบจะบล็อกการส่งเหตุการณ์ไปยังแอป แต่ UI ยังคงอยู่บนหน้าจอและไม่ถูกย่อ

ลักษณะของ Inactive เป็นแบบชั่วคราว สถานะนี้กินเวลาเท่ากับระยะเวลาของการขัดจังหวะของระบบ: ตั้งแต่ 0.1 วินาทีเมื่อปิด Control Center อย่างรวดเร็ว ไปจนถึงหลายวินาทีระหว่างสายเรียกเข้าที่มีหน้าจอโทร หลังจากสิ้นสุดการขัดจังหวะ แอปจะกลับไปยัง Active หรือเปลี่ยนไปยัง Background หากผู้ใช้เปลี่ยนไปยังแอปอื่น Inactive เป็นสถานะเดียวที่สามารถเปลี่ยนได้ทั้งสองทิศทาง: กลับไปยัง Active หรือต่อไปยัง Background

บน iOS Inactive ถูกจัดการโดยระบบโดยอัตโนมัติ นักพัฒนาไม่สามารถยืดหรือลดเวลาใน Inactive ได้ — มันถูกควบคุมโดย UIApplication อย่างสมบูรณ์ สิ่งเดียวที่นักพัฒนาสามารถทำได้คือจัดการการเปลี่ยนไปยัง Inactive ผ่าน applicationWillResignActive และการกลับมาผ่าน applicationDidBecomeActive อย่างถูกต้อง บน Android สิ่งที่เทียบเท่าคือ onPause แม้ว่าความหมายจะแตกต่าง: onPause ถูกเรียกแม้ว่า Activity จะถูกปิดบังบางส่วนโดยคอมโพเนนต์อื่น

การเปรียบเทียบ Inactive บน iOS และ Android

บน iOS Inactive เป็นสถานะแยกต่างหากในวงจรชีวิตของแอปพลิเคชัน (หนึ่งในห้า: Not Running, Active, Inactive, Background, Suspended) บน Android ไม่มีสิ่งที่เทียบเท่าโดยตรง — onPause ส่งสัญญาณว่า Activity กำลังสูญเสียโฟกัสการป้อนข้อมูลแต่อาจยังคงมองเห็นได้ (ตัวอย่างเช่น เมื่อเปิดไดอะล็อก) ความแตกต่างหลัก: iOS Inactive เป็นสถานะทั่วทั้งแอป ในขณะที่ Android onPause เป็นสถานะต่อ Activity ใน Android มัลติหน้าต่าง Activity หนึ่งสามารถอยู่ใน onPause (ไม่มีโฟกัส) ในขณะที่อีก Activity หนึ่งอยู่ใน onResume (มีโฟกัส)

คุณลักษณะiOS InactiveAndroid onPause
UI มองเห็นใช่ใช่ (บางส่วนหรือทั้งหมด)
เหตุการณ์สัมผัสไม่รับไม่รับ
ระยะเวลาจนกว่าการขัดจังหวะจะสิ้นสุดจนกว่าโฟกัสจะกลับมาหรือไปยังพื้นหลัง
สถานะถัดไปActive หรือ BackgroundonResume หรือ onStop
ระดับแอป (UIApplication)Activity
มัลติหน้าต่างหนึ่งฉากทำงานหลาย Activity ใน onPause

เมื่อใดที่ Inactive เกิดขึ้น

Inactive บน iOS เกิดขึ้นในหลายสถานการณ์ที่กำหนดไว้อย่างชัดเจน ผู้ใช้เปิด Control Center (ปัดลงจากมุมขวาบนบน iPhone X+ หรือปัดขึ้นบนรุ่นเก่า) ผู้ใช้เปิด Notification Center (ปัดลงจากมุมซ้ายบน) สายเรียกเข้าเข้ามา — ระบบแสดงหน้าจอโทรเหนือแอป มีการขอสิทธิ์ระบบ — ตำแหน่งที่ตั้ง ไมโครโฟน กล้อง รายชื่อติดต่อ บน iPad เปิด Slide Over หรือ Split View — ฉากที่ทำงานอยู่กลายเป็น Inactive

บน Android onPause (สิ่งที่เทียบเท่าของ Inactive) เกิดขึ้นในช่วงสถานการณ์ที่กว้างยิ่งขึ้น การเปิดไดอะล็อก (AlertDialog, DialogFragment) การซ้อนทับบางส่วนของ Activity โดย Activity อื่น (ตัวอย่างเช่น Activity โปร่งใสสำหรับการยืนยันตัวตน) การหมุนหน้าจอ (Activity ถูกสร้างใหม่ ลำดับ: onPause → onStop → onDestroy → onCreate → onStart → onResume) โหมดมัลติหน้าต่าง — หน้าต่างที่ไม่ทำงานได้รับ onPause แต่ละเหตุการณ์เหล่านี้ต้องการการระงับการดำเนินงานที่ใช้ทรัพยากรมาก เพื่อรักษาแบตเตอรี่และประสิทธิภาพ

swift
import UIKit

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

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func applicationWillResignActive(_ application: UIApplication) {
        // แอปเปลี่ยนไปยัง Inactive — การขัดจังหวะของระบบ
        print("การขัดจังหวะ: Control Center, สายเรียกเข้า หรือการแจ้งเตือนระบบ")

        // ระงับการดำเนินงานที่ไวต่อเวลา
        pauseVideoPlayback()
        stopContinuousDataCollection()
        hideSensitiveInformation()

        // แจ้งคอมโพเนนต์
        NotificationCenter.default.post(name: .systemInterruptionBegan, object: nil)
    }

    // กลับจาก Inactive ไปยัง Active
    func applicationDidBecomeActive(_ application: UIApplication) {
        resumeVideoPlayback()
        restartDataCollection()
        NotificationCenter.default.post(name: .systemInterruptionEnded, object: nil)
    }

    private func pauseVideoPlayback() {
        // หยุดวิดีโอชั่วคราวเพื่อไม่ให้เสียงซ้อนทับ
    }

    private func hideSensitiveInformation() {
        // ซ่อนข้อมูลที่ละเอียดอ่อนเมื่อจับภาพหน้าจอ
        // Control Center/App Switcher จับภาพหน้าจอ UI
    }
}

โค้ดแสดงการจัดการ Inactive ใน UIKit applicationWillResignActive หยุดวิดีโอชั่วคราว หยุดการรวบรวมข้อมูล และซ่อนข้อมูลที่ละเอียดอ่อน สิ่งนี้สำคัญเพราะเมื่อเปิด Control Center หรือ App Switcher ระบบจะจับภาพหน้าจอของ UI ปัจจุบัน — ผู้ใช้อาจเห็นข้อมูลที่เป็นความลับในตัวอย่างภาพ NotificationCenter อนุญาตให้คอมโพเนนต์ของแอปสมัครรับเหตุการณ์การขัดจังหวะ

Inactive บน iOS: Swift และ UIKit

บน iOS Inactive ถูกจัดการโดยเมธอดคู่หนึ่ง: applicationWillResignActive (การเปลี่ยนไปยัง Inactive) และ applicationDidBecomeActive (การกลับมาจาก Inactive) เมธอดเหล่านี้เป็นส่วนหนึ่งของ UIApplicationDelegate และถูกเรียกสำหรับทุกการเปลี่ยนผ่าน Inactive ตั้งแต่ iOS 13 และ UISceneDelegate ได้เพิ่ม sceneWillResignActive และ sceneDidBecomeActive สำหรับสถานการณ์มัลติหน้าต่าง

SceneDelegate และ Inactive แบบมัลติหน้าต่าง

บน iPad ที่ใช้ iOS 13+ แอปสามารถมีหลายฉาก (หน้าต่าง) แต่ละฉากมีวงจรชีวิตของตัวเอง ฉากหนึ่งสามารถกลายเป็น Inactive (ผู้ใช้เปลี่ยนไปยังฉากอื่น) ในขณะที่อีกฉากหนึ่งยังคง Active นี่คือความแตกต่างที่สำคัญจาก iPhone ที่ Inactive เป็นสถานะทั่วโลกสำหรับทั้งแอป เมื่อพัฒนาสำหรับ iPad คุณต้องจัดการ Inactive สำหรับแต่ละฉากแยกกัน

swift
import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    // ฉากกลายเป็นไม่ทำงาน
    func sceneWillResignActive(_ scene: UIScene) {
        // บน iPad ฉากนี้สูญเสียโฟกัส แต่ฉากอื่นอาจยังทำงานอยู่
        print("ฉากสูญเสียการทำงาน")

        // ระงับงานของฉากนี้
        pauseSceneSpecificOperations()
    }

    // ฉากกลายเป็นทำงาน
    func sceneDidBecomeActive(_ scene: UIScene) {
        print("ฉากกลายเป็นทำงานแล้ว")
        resumeSceneSpecificOperations()
    }

    private func pauseSceneSpecificOperations() {
        // ระงับการดำเนินงานเฉพาะของฉากนี้
    }

    private func resumeSceneSpecificOperations() {
        // เริ่มการดำเนินงานใหม่เมื่อโฟกัสกลับมา
    }
}

// AppDelegate ยังคงเป็นจุดเริ่มต้น มอบหมายให้ฉาก
@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(
        _ application: UIApplication,
        configurationForConnecting connectingSceneSession: UISceneSession,
        options: UIScene.ConnectionOptions
    ) -> UISceneConfiguration {
        return UISceneConfiguration(
            name: "Default Configuration",
            sessionRole: connectingSceneSession.role
        )
    }
}

โค้ดแสดง SceneDelegate สำหรับจัดการ Inactive ในระดับฉาก sceneWillResignActive ถูกเรียกเมื่อหน้าต่างเฉพาะสูญเสียโฟกัส — สิ่งนี้สามารถเกิดขึ้นเมื่อสลับระหว่างหน้าต่างบน iPad AppDelegate กำหนดค่า UISceneConfiguration เพื่อรองรับมัลติหน้าต่าง แต่ละฉากมีสถานะอิสระและนักพัฒนาต้องจัดการแยกกัน

Inactive บน Android: onPause และการมองเห็น

บน Android สิ่งที่เทียบเท่าโดยตรงของ iOS Inactive คือเมธอด onPause() ของวงจรชีวิต Activity มันถูกเรียกเมื่อ Activity สูญเสียโฟกัสการป้อนข้อมูลแต่อาจยังคงมองเห็นได้ สถานการณ์ทั่วไป: การเปิดไดอะล็อก การเริ่ม Activity อื่นในแอปเดียวกัน สายเรียกเข้า การกดปุ่ม Home หรือ Recents ใน onPause นักพัฒนาควรระงับการดำเนินงานที่ใช้ทรัพยากรมาก — อนิเมชัน การเล่นวิดีโอ การทำงานกับกล้อง

ความแตกต่างที่สำคัญของ Android คือ onPause มาก่อน onStop เสมอ แต่ไม่ใช่ในทางกลับกัน Activity สามารถรับ onPause โดยไม่มี onStop (ตัวอย่างเช่น เมื่อเปิด Activity โปร่งใส) นอกจากนี้ onPause สามารถถูกเรียกหลายครั้งในช่วงอายุของ Activity — ในการสลับโฟกัสแต่ละครั้ง อย่าวางลอจิกครั้งเดียวใน onPause — ใช้ onStop สำหรับการดำเนินงานสุดท้ายและ onPause สำหรับการระงับการกระทำเชิงโต้ตอบเท่านั้น

kotlin
class VideoPlayerActivity : AppCompatActivity() {

    private var exoPlayer: ExoPlayer? = null
    private var currentPosition: Long = 0L

    override fun onPause() {
        super.onPause()
        // แอปสูญเสียโฟกัส — หยุดวิดีโอชั่วคราว
        exoPlayer?.let { player ->
            if (player.isPlaying) {
                currentPosition = player.currentPosition
                player.pause()
            }
        }
        // ซ่อนข้อมูลที่ละเอียดอ่อน (GDPR/หน้าจอธนาคาร)
        if (window.decorView.systemUiVisibility and
            View.SYSTEM_UI_FLAG_SECURE == 0
        ) {
            hideSensitiveOverlay()
        }
    }

    override fun onResume() {
        super.onResume()
        // โฟกัสกลับมา — เริ่มการเล่นใหม่
        exoPlayer?.seekTo(currentPosition)
        exoPlayer?.play()
        showSensitiveOverlay()
    }

    private fun hideSensitiveOverlay() {
        // วางหน้าจอสีดำทับข้อมูลทางการเงิน
    }
}

โค้ดแสดงการจัดการ onPause ที่ถูกต้องสำหรับเครื่องเล่นวิดีโอ ExoPlayer ถูกหยุดชั่วคราวเมื่อสูญเสียโฟกัส และตำแหน่งการเล่นถูกบันทึก เมื่อกลับไปยัง onResume เครื่องเล่นจะเล่นต่อจากตำแหน่งที่บันทึกไว้ นอกจากนี้ยังแสดงรูปแบบการซ่อนข้อมูลที่ละเอียดอ่อน — สำคัญสำหรับแอปทางการเงินและการแพทย์ที่ต้องการการปกป้องจากภาพหน้าจอเมื่อสลับแอป

แนวทางปฏิบัติที่ดีที่สุดสำหรับการจัดการ Inactive

กฎข้อแรก — ซ่อนข้อมูลที่เป็นความลับเมื่อเปลี่ยนไปยัง Inactive เมื่อผู้ใช้เปิด Control Center หรือ App Switcher iOS จะจับภาพหน้าจอปัจจุบัน บน Android เช่นเดียวกัน ระบบจะแสดงตัวอย่างของ Activity ล่าสุดใน Recents ใช้ UIApplication.shouldSnapshotSecureApp (iOS 16+) หรือ FLAG_SECURE (Android) เพื่อป้องกันหน้าจอที่เป็นความลับ

กฎข้อที่สอง — หยุดอนิเมชันและสื่อชั่วคราว Inactive ไม่ใช่เวลาที่ดีสำหรับการเล่นวิดีโอหรืออนิเมชัน เพราะผู้ใช้ไม่สามารถมองเห็นได้ นอกจากนี้ การเล่นในพื้นหลังอาจทำให้เสียงซ้อนทับกับเสียงระบบ (เสียงเรียกเข้า การแจ้งเตือน) หยุด AVPlayer, ExoPlayer และ UIView.animateเมื่อไปยัง Inactive และเริ่มใหม่เมื่อกลับไปยัง Active

กฎข้อที่สาม — บล็อกการป้อนข้อมูล หากแอปมีฟอร์มป้อนข้อมูลหรือร่างเอกสาร ให้ล็อกแป้นพิมพ์และฟิลด์ป้อนข้อมูลเมื่อไปยัง Inactive สิ่งนี้ป้องกันการป้อนข้อมูลโดยไม่ตั้งใจเมื่อกลับมาและป้องกันการสกัดกั้นข้อมูลผ่านการซ้อนทับของระบบ บน iOS ให้ปลดผู้ตอบสนองคนแรก (view.endEditing(true)), บน Android — ล้างโฟกัส (currentFocus?.clearFocus())

กฎข้อที่สี่ — อย่าดำเนินงานที่ยาวนานใน applicationWillResignActive หรือ onPause เมธอดเหล่านี้ควรเสร็จสิ้นในเสี้ยววินาที หากคุณต้องการบันทึกข้อมูลจำนวนมาก ให้เริ่มบันทึกในเธรดพื้นหลังและทำให้เสร็จใน applicationDidEnterBackground หรือ onStop iOS ให้ 5 วินาทีสำหรับการดำเนินการ applicationWillResignActive หลังจากนั้นระบบอาจบังคับปิดแอป

swift
import UIKit

final class SecureOverlayManager {
    private var blurView: UIVisualEffectView?

    func showBlurOverlay() {
        guard let window = UIApplication.shared.keyWindow,
              blurView == nil
        else { return }

        let blur = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
        blur.frame = window.bounds
        blur.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        window.addSubview(blur)
        blurView = blur
    }

    func removeBlurOverlay() {
        blurView?.removeFromSuperview()
        blurView = nil
    }
}

// การใช้งานใน AppDelegate
func applicationWillResignActive(_ application: UIApplication) {
    SecureOverlayManager().showBlurOverlay()
}

func applicationDidBecomeActive(_ application: UIApplication) {
    SecureOverlayManager().removeBlurOverlay()
}

โค้ดแสดงการใช้งานการซ้อนทับที่ปลอดภัยสำหรับการปกป้องข้อมูลระหว่างการเปลี่ยนไปยัง Inactive UIVisualEffectView ที่มีเอฟเฟกต์เบลอถูกวางซ้อนบน UI ทั้งหมดเมื่อไปยัง Inactive และถูกลบออกเมื่อกลับไปยัง Active สิ่งนี้รับประกันว่าข้อมูลที่เป็นความลับจะไม่ปรากฏในภาพหน้าจอของ App Switcher และ Control Center เช่นเดียวกัน คุณสามารถใช้ UIImageView พร้อมโลโก้สำหรับการซ้อนทับที่มีตราสินค้า

คำถามที่พบบ่อย

Inactive มาก่อน Background เสมอหรือไม่?

ใช่ Inactive เป็นสถานะกลางที่จำเป็นก่อนการเปลี่ยนไปยัง Background บน iOS แอปไม่สามารถไปจาก Active ตรงไปยัง Background ได้ — มันจะกลายเป็น Inactive ก่อน จากนั้นจึง Background บน Android เช่นเดียวกัน onPause ถูกเรียกก่อน onStop เสมอ สิ่งนี้เปิดโอกาสให้นักพัฒนาเตรียมข้อมูลสำหรับบันทึกก่อนที่จะไปยังพื้นหลังอย่างสมบูรณ์

แอปสามารถกลายเป็น Inactive โดยไม่มีการขัดจังหวะได้หรือไม่?

ใช่ บน iPad เมื่อเปิด Slide Over หรือ Split View ฉากที่ทำงานอยู่จะกลายเป็น Inactive แม้ว่าจะไม่มีการขัดจังหวะของระบบเกิดขึ้น — ผู้ใช้เพียงแค่โต้ตอบกับอีกฉากหนึ่ง นี่คือคุณสมบัติของ iPadOS แบบมัลติหน้าต่าง บน iPhone Inactive ถูกกระตุ้นโดยการขัดจังหวะของระบบเสมอ — สายเรียกเข้า การแจ้งเตือน Control Center หรือ Notification Center

แอปสามารถอยู่ใน Inactive ได้นานเท่าใด?

โดยปกติตั้งแต่ 0.1 ถึง 2 วินาที ระหว่างสายเรียกเข้าที่มีหน้าจอโทร — สูงสุด 30 วินาที (จนกว่าผู้ใช้จะรับหรือปฏิเสธสาย) iOS ไม่จำกัดเวลาใน Inactive อย่างบังคับ แต่ระบบอาจปิดแอปหากไม่ตอบสนองต่อเหตุการณ์ (watchdog) บน Android onPause ไม่มีข้อจำกัดด้านเวลา แต่แนะนำให้ทำงานเสร็จภายใน 200 ms

scenePhase ใน SwiftUI ระหว่าง Inactive คืออะไร?

ScenePhase.inactive — ค่า enum ScenePhase ที่ตั้งค่าเมื่อฉากอยู่เบื้องหน้าแต่ไม่ได้รับเหตุการณ์ ใน SwiftUI คุณสามารถสังเกตมันผ่าน @Environment(\.scenePhase) และตอบสนองผ่าน onChange เมื่อเปลี่ยนจาก .active เป็น .inactive ให้หยุดตัวจับเวลาและอนิเมชันชั่วคราว เมื่อกลับไปยัง .active ให้เริ่มใหม่ เมื่อไปยัง .background ให้บันทึกสถานะ

จำเป็นต้องซ่อน UI ระหว่าง Inactive สำหรับแอปทั้งหมดหรือไม่?

ไม่ สำหรับแอปที่จัดการข้อมูลที่เป็นความลับเท่านั้น: ธนาคาร การแพทย์ องค์กร และแอปส่งข้อความที่มีแชทส่วนตัว สำหรับเกมและแอปบันเทิง ไม่จำเป็นต้องซ่อน UI อย่างไรก็ตาม การหยุดเกมเพลย์และเสียงระหว่าง Inactive เป็นแนวทางปฏิบัติที่ดีเพื่อหลีกเลี่ยงการซ้อนทับของเสียงกับการแจ้งเตือนระบบ Apple แนะนำให้ซ่อนข้อมูลที่ละเอียดอ่อนแต่ไม่ได้บังคับ

สรุป

  • Inactive — สถานะเปลี่ยนผ่านระหว่าง Active และ Background แอปมองเห็นได้แต่ไม่โต้ตอบ
  • สาเหตุ — Control Center, Notification Center, สายเรียกเข้า, สิทธิ์ระบบ, Siri, Apple Pay
  • การจัดการบน iOS — applicationWillResignActive สำหรับหยุดอนิเมชัน สื่อ และซ่อนข้อมูลที่ละเอียดอ่อน
  • SwiftUI — scenePhase .inactive ผ่าน Environment, onChange สำหรับเอฟเฟกต์ข้างเคียง
  • Android — onPause เป็นสิ่งที่เทียบเท่า รองรับมัลติหน้าต่างและการซ้อนทับ Activity บางส่วน
  • ความปลอดภัย — การซ้อนทับแบบเบลอหรือ FLAG_SECURE เพื่อป้องกันภาพหน้าจอ App Switcher และ Control Center
  • ลักษณะชั่วคราว — Inactive กินเวลาจนกว่าการขัดจังหวะจะสิ้นสุด จากนั้นกลับไปยัง Active หรือไปยัง Background

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม