Inactive — Active और Background के बीच एप्लिकेशन जीवनचक्र में एक संक्रमणकालीन अवस्था, जिसमें ऐप स्क्रीन पर दिखाई देता है लेकिन स्पर्श ईवेंट प्राप्त नहीं करता। हम समझाते हैं कि iOS और Android पर Inactive कैसे उत्पन्न होता है, कौन से डेलिगेट विधियाँ इसके लिए ज़िम्मेदार हैं और रुकावटों — कॉल, सूचनाएँ और सिस्टम जेस्चर — को सही ढंग से कैसे संभालें।
मुख्य बिंदु
Inactive मोबाइल ऐप जीवनचक्र में एक मध्यवर्ती अवस्था है जो Active और Background के बीच संक्रमण के दौरान होती है। इस अवस्था में, ऐप अभी भी अग्रभूमि में है और उपयोगकर्ता को दिखाई देता है, लेकिन स्पर्श ईवेंट, कुंजी दबाव या अन्य UI ईवेंट प्राप्त नहीं करता। सिस्टम ऐप को ईवेंट वितरण को अवरुद्ध करता है, लेकिन UI स्क्रीन पर रहता है और छोटा नहीं होता।
Inactive की प्रकृति अस्थायी है। यह अवस्था ठीक उतनी ही समय तक रहती है जितनी सिस्टम रुकावट रहती है: Control Center को जल्दी बंद करने पर 0.1 सेकंड से लेकर कॉल स्क्रीन के साथ इनकमिंग कॉल के दौरान कई सेकंड तक। रुकावट समाप्त होने के बाद, ऐप या तो Active पर लौटता है या Background में चला जाता है यदि उपयोगकर्ता ने दूसरे ऐप पर स्विच किया हो। Inactive एकमात्र अवस्था है जो दोनों दिशाओं में संक्रमण कर सकती है: वापस Active में या आगे Background में।
iOS पर, Inactive सिस्टम द्वारा स्वचालित रूप से प्रबंधित किया जाता है। डेवलपर Inactive में बिताए समय को बढ़ा या घटा नहीं सकता — यह पूरी तरह से UIApplication द्वारा नियंत्रित होता है। डेवलपर केवल एक ही चीज़ कर सकता है — applicationWillResignActive के माध्यम से Inactive में संक्रमण और applicationDidBecomeActive के माध्यम से वापसी को सही ढंग से संभालना। Android पर, समतुल्य onPause है, हालाँकि शब्दार्थ भिन्न है: onPause तब भी कॉल किया जाता है जब कोई Activity किसी अन्य घटक द्वारा आंशिक रूप से ढकी होती है।
iOS पर, Inactive एप्लिकेशन जीवनचक्र की एक अलग अवस्था है (पाँच में से एक: Not Running, Active, Inactive, Background, Suspended)। Android पर कोई सीधा समतुल्य नहीं है — onPause संकेत देता है कि Activity इनपुट फोकस खो रही है लेकिन दिखाई दे सकती है (उदाहरण के लिए, जब कोई डायलॉग खुलता है)। मुख्य अंतर: iOS Inactive समग्र ऐप की अवस्था है, जबकि Android onPause प्रति-Activity अवस्था है। Android मल्टी-विंडो में, एक Activity onPause (बिना फोकस) में हो सकती है जबकि दूसरी onResume (फोकस के साथ) में हो।
| विशेषता | iOS Inactive | Android onPause |
|---|---|---|
| UI दृश्य | हाँ | हाँ (आंशिक या पूर्ण) |
| स्पर्श ईवेंट | प्राप्त नहीं करता | प्राप्त नहीं करता |
| अवधि | रुकावट समाप्त होने तक | फोकस लौटने या पृष्ठभूमि में जाने तक |
| अगली अवस्था | Active या Background | onResume या onStop |
| स्तर | ऐप (UIApplication) | Activity |
| मल्टी-विंडो | एक सीन सक्रिय | कई Activity onPause में |
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 प्राप्त करती है। इनमें से प्रत्येक घटना में बैटरी और प्रदर्शन को संरक्षित करने के लिए संसाधन-गहन संचालन को निलंबित करना आवश्यक है।
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 का स्क्रीनशॉट लेते हैं
}
}कोड UIKit में Inactive हैंडलिंग दिखाता है। applicationWillResignActive वीडियो को रोकता है, डेटा संग्रह रोकता है और संवेदनशील जानकारी छिपाता है। यह महत्वपूर्ण है क्योंकि जब Control Center या App Switcher खोला जाता है, सिस्टम वर्तमान UI का स्क्रीनशॉट लेता है — उपयोगकर्ता पूर्वावलोकन में गोपनीय डेटा देख सकता है। NotificationCenter ऐप घटकों को रुकावट घटनाओं की सदस्यता लेने की अनुमति देता है।
iOS पर, Inactive को विधियों की एक जोड़ी द्वारा संभाला जाता है: applicationWillResignActive (Inactive में संक्रमण) और applicationDidBecomeActive (Inactive से वापसी)। ये विधियाँ UIApplicationDelegate का हिस्सा हैं और Inactive के माध्यम से प्रत्येक संक्रमण के लिए कॉल की जाती हैं। iOS 13 और UISceneDelegate के बाद से, मल्टी-विंडो परिदृश्यों के लिए sceneWillResignActive और sceneDidBecomeActive जोड़े गए हैं।
iOS 13+ वाले iPad पर, एक ऐप में कई सीन (विंडो) हो सकते हैं। प्रत्येक सीन का अपना जीवनचक्र होता है। एक सीन Inactive हो सकता है (उपयोगकर्ता ने दूसरे सीन पर स्विच किया) जबकि दूसरा Active रहता है। यह iPhone से एक महत्वपूर्ण अंतर है, जहाँ Inactive पूरे ऐप के लिए एक वैश्विक अवस्था है। iPad के लिए विकास करते समय, आपको प्रत्येक सीन के लिए अलग से Inactive संभालना होगा।
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
)
}
}कोड सीन स्तर पर Inactive संभालने के लिए SceneDelegate दिखाता है। sceneWillResignActive तब कॉल किया जाता है जब कोई विशिष्ट विंडो फोकस खोती है — यह iPad पर विंडो के बीच स्विच करते समय हो सकता है। AppDelegate मल्टी-विंडो समर्थन के लिए UISceneConfiguration कॉन्फ़िगर करता है। प्रत्येक सीन की स्वतंत्र अवस्था होती है और डेवलपर को उन्हें अलग से संभालना चाहिए।
Android पर, iOS Inactive का सीधा समतुल्य Activity जीवनचक्र की onPause() विधि है। यह तब कॉल की जाती है जब Activity इनपुट फोकस खोती है लेकिन दिखाई दे सकती है। विशिष्ट परिदृश्य: डायलॉग खोलना, उसी ऐप में दूसरी Activity लॉन्च करना, इनकमिंग कॉल, Home या Recents बटन दबाना। onPause में, डेवलपर को संसाधन-गहन संचालन — एनिमेशन, वीडियो प्लेबैक, कैमरा कार्य — निलंबित करना चाहिए।
Android का एक महत्वपूर्ण अंतर यह है कि onPause हमेशा onStop से पहले होता है, लेकिन इसके विपरीत नहीं। एक Activity onPause बिना onStop के प्राप्त कर सकती है (उदाहरण के लिए, पारदर्शी Activity खोलते समय)। साथ ही, onPause को Activity के जीवनकाल में कई बार कॉल किया जा सकता है — प्रत्येक फोकस स्विच पर। onPause में एक बार की लॉजिक न रखें — अंतिम संचालन के लिए onStop का उपयोग करें और केवल इंटरैक्टिव क्रियाओं को निलंबित करने के लिए onPause का उपयोग करें।
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 में संक्रमण करते समय गोपनीय डेटा छिपाएँ। जब उपयोगकर्ता Control Center या App Switcher खोलता है, iOS वर्तमान स्क्रीन का स्क्रीनशॉट लेता है। Android पर, इसी तरह, सिस्टम Recents में अंतिम Activity का पूर्वावलोकन दिखाता है। गोपनीय स्क्रीन की सुरक्षा के लिए UIApplication.shouldSnapshotSecureApp (iOS 16+) या FLAG_SECURE (Android) का उपयोग करें।
दूसरा नियम — एनिमेशन और मीडिया रोकें। Inactive वीडियो या एनिमेशन चलाने का अच्छा समय नहीं है, क्योंकि उपयोगकर्ता उन्हें देख नहीं सकता। इसके अलावा, पृष्ठभूमि प्लेबैक ऑडियो को सिस्टम ध्वनियों (रिंगटोन, सूचना) के साथ ओवरलैप कर सकता है। Inactive पर जाते समय AVPlayer, ExoPlayer और UIView.animate रोकें और Active पर लौटने पर फिर से शुरू करें।
तीसरा नियम — डेटा इनपुट अवरुद्ध करें। यदि ऐप में इनपुट फ़ॉर्म या ड्राफ्ट हैं, तो Inactive पर जाते समय कीबोर्ड और इनपुट फ़ील्ड लॉक करें। यह वापसी पर आकस्मिक इनपुट को रोकता है और सिस्टम ओवरले के माध्यम से डेटा अवरोधन से बचाता है। iOS पर, प्रथम प्रतिसादकर्ता छोड़ें (view.endEditing(true)), Android पर — फोकस साफ़ करें (currentFocus?.clearFocus()).
चौथा नियम — applicationWillResignActive या onPause में लंबे संचालन न करें। ये विधियाँ सेकंड के अंश में पूरी होनी चाहिए। यदि आपको बड़ी मात्रा में डेटा सहेजने की आवश्यकता है, तो पृष्ठभूमि थ्रेड पर सहेजना शुरू करें और applicationDidEnterBackground या onStop में इसे पूरा करें। iOS applicationWillResignActive के निष्पादन के लिए 5 सेकंड देता है, जिसके बाद सिस्टम ऐप को बलपूर्वक समाप्त कर सकता है।
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 Inactive पर जाते समय पूरे UI के ऊपर रखा जाता है और Active पर लौटने पर हटा दिया जाता है। यह सुनिश्चित करता है कि गोपनीय डेटा App Switcher और Control Center स्क्रीनशॉट में दिखाई न दे। इसी तरह, आप ब्रांडेड ओवरले के लिए लोगो के साथ UIImageView का उपयोग कर सकते हैं।
अक्सर पूछे जाने वाले प्रश्न
हाँ। Inactive iOS पर Background में जाने से पहले एक अनिवार्य मध्यवर्ती अवस्था है। कोई ऐप Active से सीधे Background में नहीं जा सकता — पहले वह Inactive होता है, फिर Background। Android पर, इसी तरह, onPause हमेशा onStop से पहले कॉल किया जाता है। यह डेवलपर को पूरी तरह पृष्ठभूमि में जाने से पहले डेटा को सहेजने के लिए तैयार करने का अवसर देता है।
हाँ। iPad पर, Slide Over या Split View लॉन्च करते समय, सक्रिय सीन Inactive हो जाता है, भले ही कोई सिस्टम रुकावट न हो — उपयोगकर्ता बस दूसरे सीन के साथ इंटरैक्ट कर रहा है। यह मल्टी-विंडो iPadOS की विशेषता है। iPhone पर, Inactive हमेशा सिस्टम रुकावट — कॉल, सूचना, Control Center या Notification Center द्वारा ट्रिगर होता है।
आमतौर पर 0.1 से 2 सेकंड तक। कॉल स्क्रीन के साथ इनकमिंग कॉल के दौरान — 30 सेकंड तक (जब तक उपयोगकर्ता कॉल का उत्तर न दे या अस्वीकार न करे)। iOS Inactive में समय को बलपूर्वक सीमित नहीं करता, लेकिन सिस्टम ऐप को समाप्त कर सकता है यदि वह ईवेंट (watchdog) पर प्रतिक्रिया नहीं देता। Android पर, onPause की कोई समय सीमा नहीं है, लेकिन 200 ms में कार्य पूरा करने की अनुशंसा की जाती है।
ScenePhase.inactive — ScenePhase एनम मान जो तब सेट होता है जब सीन अग्रभूमि में होता है लेकिन ईवेंट प्राप्त नहीं करता। SwiftUI में, आप इसे @Environment(\.scenePhase) के माध्यम से देख सकते हैं और onChange के माध्यम से प्रतिक्रिया कर सकते हैं। .active से .inactive में संक्रमण करते समय, टाइमर और एनिमेशन रोकें। .active पर लौटने पर, उन्हें फिर से शुरू करें। .background पर जाते समय, स्थिति सहेजें।
नहीं, केवल उन ऐप्स के लिए जो गोपनीय डेटा संभालते हैं: बैंकिंग, चिकित्सा, कॉर्पोरेट और निजी चैट वाले मैसेजिंग ऐप्स। गेम और मनोरंजन ऐप्स के लिए, UI छिपाना आवश्यक नहीं है। हालाँकि, Inactive के दौरान गेमप्ले और ध्वनि को रोकना सिस्टम सूचनाओं के साथ ऑडियो ओवरलैप से बचने के लिए अच्छा अभ्यास है। Apple संवेदनशील डेटा छिपाने की सिफारिश करता है लेकिन इसकी आवश्यकता नहीं है।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें