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 ব্যবহার করতে পারেন।
সচরাচর জিজ্ঞাসিত প্রশ্ন
হ্যাঁ। iOS-এ Background-এ যাওয়ার আগে Inactive একটি বাধ্যতামূলক মধ্যবর্তী অবস্থা। কোনো অ্যাপ 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 অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন