Önemli Noktalar
App Lifecycle, bir mobil uygulamanın tüm olası durumlarını ve aralarındaki geçişleri tanımlayan sonlu bir durum makinesidir. Her durum, uygulamanın kod çalıştırıp çalıştıramayacağını, kullanıcı arayüzünü görüntüleyip görüntüleyemeyeceğini ve kaynak tüketip tüketemeyeceğini belirler. iOS ve Android benzer ancak aynı olmayan modellere sahiptir — farklılıklar işletim sistemi mimarisinden kaynaklanır: iOS katı bellek kontrolü kullanır (suspended durumu), Android ise onSaveInstanceState aracılığıyla esnek süreç yönetimi kullanır.
iOS'ta yaşam döngüsü ön plan/arka plana sıkı sıkıya bağlıdır: uygulama ya aktiftir ya da askıya alınmıştır. Android'de yaşam döngüsü daha ayrıntılıdır — bir Activity/Pencere 6+ durumdan geçer ve sürecin kendisi ProcessLifecycleOwner aracılığıyla ek bir yaşam döngüsüne sahiptir. Modern uygulamalar (2024'ten itibaren) giderek yaşam döngüsü tabanlı mimari modeller kullanmaktadır: SwiftUI Lifecycle (iOS 16+) .scenePhase ortamı aracılığıyla, Compose Lifecycle LifecycleEventObserver aracılığıyla. Bu modeller bağlam değiştirmeyi otomatik olarak işler ve bellek sızıntılarını önler. Google'a göre, Android'de doğru yaşam döngüsü işleme, arka plan çalışması sırasında bellek tüketimini %30-40 oranında azaltır.
iOS'ta uygulama yaşam döngüsü, UIApplicationDelegate sınıfı (AppDelegate) aracılığıyla yönetilir. Ana yöntemler: application(_:didFinishLaunchingWithOptions:) — ilk başlatmada ilkleme; applicationDidBecomeActive — uygulama görünür ve etkileşime hazır; applicationWillResignActive — etkin olmayan duruma geçiş (gelen çağrı, bildirim perdesini kapatma); applicationDidEnterBackground — uygulama gizli, veri kaydetmek için ~5 saniye; applicationWillEnterForeground — arka plandan dönüş; applicationWillTerminate — sonlandırma (yalnızca askıya alma olmayan eski uygulamalar için çağrılır).
iOS 13'ten başlayarak Apple, iPad ve macOS Catalyst'te çok pencereli uygulamaları desteklemek için SceneDelegate'i (UISceneDelegate) tanıttı. SceneDelegate, her bir sahnenin (pencere) yaşam döngüsünü yönetir: scene(_:willConnectTo:options:) — sahne oluşturma; sceneDidBecomeActive — sahne aktif; sceneWillResignActive — sahne odağı kaybeder; sceneDidEnterBackground — sahne gizli. AppDelegate küresel olayları (veri yükleme, push bildirimleri) işlerken, SceneDelegate her pencerenin kullanıcı arayüzü durumunu yönetir. SwiftUI'de yaşam döngüsü, @Environment(\.scenePhase): .active, .inactive, .background ortam değeri aracılığıyla yönetilir — bu, hem SwiftUI hem de UIKit uygulamaları için birleşik bir API sağlar.
Android'de yaşam döngüsü, Application sınıfıyla başlar — herhangi bir Activity'den önce oluşturulan bir singleton. Application.onCreate() yöntemi, küresel ilkleme (Analytics, DI, Crash Reporting) için kullanılan ilk giriş noktasıdır. Bundan sonra Activity şu sırayla başlatılır: onCreate() → onStart() → onResume(). Küçültüldüğünde: onPause() → onStop() → onSaveInstanceState(). Yok edildiğinde: onDestroy(). Geri dönüldüğünde: onRestart() → onStart() → onResume().
ProcessLifecycleOwner (AndroidX Lifecycle 2.2+'dan) bireysel bir Activity'nin değil, tüm sürecin yaşam döngüsünü izler. İki durum sağlar: ON_RESUME (uygulama ön planda) ve ON_STOP (uygulama gizli). ProcessLifecycleOwner, süreç düzeyinde “uygulamanın ne zaman arka plana geçtiği” sorununu çözer — bu, SDK'ler, kitaplıklar ve modüler uygulamalar için kritiktir. Jetpack Compose'da yaşam döngüsü, LifecycleEventObserver ve collectAsStateWithLifecycle aracılığıyla yönetilir; bu, arka plan modunda veri toplamayı otomatik olarak askıya alır. Android 14 (API 34), Service.onTimeout aracılığıyla ön plan hizmeti yaşam döngüsü bildirimi ekledi — hizmet 6 saat içinde tamamlanmalıdır, aksi takdirde sistem onu zorla durdurur.
| iOS | Android | Açıklama |
|---|---|---|
| Not Running | — | Uygulama başlatılmadı |
| didFinishLaunching | Application.onCreate | Başlatmada ilk ilkleme |
| Active | onResume | Uygulama görünür ve girdi kabul ediyor |
| Inactive | onPause | Geçici odak kaybı (çağrı, bildirim perdesi) |
| Background | onStop | Uygulama gizli, kod çalışıyor olabilir |
| Suspended | — | Kod çalışmıyor, bellek ayrılmış |
| Will Terminate | onDestroy | Uygulama sonlanıyor |
Temel fark: iOS, arka plana girdikten 5-10 saniye sonra uygulamayı zorla Suspended (kod çalışmayı durdurur) durumuna geçirir. Android, daha uzun bir süre boyunca arka plan çalışmasına (servisler, WorkManager) izin verir, ancak Doze Modu (Android 6+) ve arka plan kısıtlamalarının (Android 12+) sınırlamalarıyla. Android'deki ProcessLifecycleOwner, iOS'taki UIApplicationDidEnterBackgroundNotification'un eşdeğeridir; farkı, yalnızca odak kaybından sonra değil, arka plana her geçişte tetiklenmesidir.
Tüm yaşam döngüsü durumlarını işleyen temel AppDelegate uygulaması. Arka plana geçerken veri kaydetme ve geri dönerken kullanıcı arayüzünü güncelleme.
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, yaşam döngüsünün merkezi noktasıdır. applicationDidEnterBackground kritik bir yöntemdir: iOS kaydetmek için ~5 saniye verir. applicationDidBecomeActive — kullanıcı arayüzünü güncelleyin, animasyonları yeniden başlatın. SceneDelegate (iOS 13+) için yaşam döngüsü mantığı sahnelere dağıtılır: sceneDidBecomeActive / sceneDidEnterBackground bireysel pencereleri yönetir.
Çok pencereli iPad uygulamaları için SceneDelegate. Her sahnenin, diğer pencerelerden bağımsız olarak kendi yaşam döngüsü vardır.
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, bireysel bir sahnenin yaşam döngüsünü yönetir. sceneDidBecomeActive / sceneDidEnterBackground, belirli bir pencere için AppDelegate yöntemlerinin eşdeğerleridir. sceneDidDisconnect, bir sahne kapatıldığında çağrılır (kullanıcı iPad'de bir pencere kapattı). iOS 12 ve altıyla uyumluluk için AppDelegate, SceneDelegate mantığını kopyalamalıdır. iOS 17+'da, scenePhase'e göre görevleri otomatik olarak duraklatmak/devam ettirmek için @Observable kullanabilirsiniz.
ProcessLifecycleOwner, uygulamanın süreç düzeyinde ön planda mı yoksa arka planda mı olduğunu izler. Bu, küresel yaşam döngüsü yönetimi için en uygun yaklaşımdır.
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, uygulama düzeyinde arka plana geçişi izlemenin tek doğru yoludur. ON_START, uygulama görünür hale geldiğinde (ön plan), ON_STOP — tamamen gizlendiğinde (arka plan) tetiklenir. Activity yaşam döngüsünün aksine, ProcessLifecycleOwner belirli bir ekrana bağlı değildir. Jetpack Compose için manuel izleme yerine LifecycleResumeEffect veya collectAsStateWithLifecycle kullanın.
ViewModel + Lifecycle, yaşam döngüsü yönetimi için doğru Android mimarisidir. ViewModel, onDestroy'de otomatik olarak temizlenir ve sızıntıları önler.
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 — kaynaklar serbest bırakılıyor")
}
}
// Activity'de
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 — animasyonlar duraklatılıyor")
}
override fun onDestroy() {
super.onDestroy()
Logger.d("Activity destroyed — temizlik")
}
}
ViewModel ekran döndürmeye dayanır ve yalnızca Activity sona erdiğinde yok edilir. onCleared(), kaynakları serbest bırakmak ve akış aboneliklerini iptal etmek için kullanılır. LiveData, onPause'da gözlemi otomatik olarak duraklatır ve onResume'da devam ettirir — bu, arka plan çalışması sırasında sızıntılara ve çökmelere karşı koruma sağlar. Compose'da aynı amaç için collectAsStateWithLifecycle() kullanın.
Sıkça Sorulan Sorular
Küçültüldüğünde, uygulama aktiften etkin değile (kısaca), ardından arka plana geçer. Birkaç saniye sonra sistem onu suspended durumuna geçirebilir — kod çalışmaz, bellek ayrılır. Bellek yetersiz olduğunda, sistem askıya alınan uygulamayı sonlandırır (willTerminate çağrılmaz). Verilerinizi applicationDidEnterBackground'da kaydedin — bu, kaydetmek için son garanti edilen noktadır.
Minimum zorunlu: applicationDidEnterBackground — kullanıcı verilerini kaydet; applicationWillEnterForeground — kullanıcı arayüzünü güncelle; Android'de onPause — animasyonları/sensörleri duraklat. ProcessLifecycleOwner işlemeyi basitleştirir: onResume — onPause ön plan için, onStart — onStop görünürlük için. Diğer durumları gerektiği gibi işleyin — tüm durumlar her uygulama için kritik değildir.
AppDelegate, tüm uygulamanın küresel temsilcisidir (başlatma, arka plan geçişi). SceneDelegate (iOS 13+), bireysel bir pencerenin (sahne) yaşam döngüsünü yönetir — çok pencereli iPad uygulamalarında her sahnenin kendi yaşam döngüsü vardır. iOS 12 ve altı için tüm yaşam döngüsü AppDelegate aracılığıyla yönetilir. iPadOS 16+ ile SceneDelegate, Stage Manager için zorunludur.
ProcessLifecycleOwner, bireysel bir Activity'nin değil, tüm uygulamanın (sürecin) yaşam döngüsünü izleyen AndroidX Lifecycle'dan bir bileşendir. İki ana olay sağlar: ON_RESUME (uygulama ön planda) ve ON_STOP (uygulama arka planda). SDK'lerin, analizlerin, ağ monitörlerinin başlatılması/temizlenmesi için kullanılır — mevcut ekrandan bağımsız olarak uygulamanın arka plana geçişine tepki vermesi gereken her şey.
Jetpack Compose'da, LocalLifecycleOwner.current.lifecycle veya collectAsStateWithLifecycle() işlevi aracılığıyla LifecycleEventObserver kullanın. Compose ekranları için LifecycleResumeEffect kullanın — DisposableEffect'e benzer, onResume'da çalışır ve onPause'da temizlenir. lifecycleScope.launchWhenResumed — arka planda otomatik olarak askıya alınan bir coroutine.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun