Not Running — nedir, yaşam döngüsünün başlangıç durumu

Yazar: IT Sectr Yayınlanma: 2026-03-03 Okuma süresi: 11 dk

Not Running — henüz başlatılmamış veya zaten çalışmasını tamamlamış bir mobil uygulamanın yaşam döngüsünün başlangıç durumu. iOS ve Android’in bu durumu nasıl yönettiğini, hangi olayların Not Running’den geçişe yol açtığını ve Swift ve Kotlin’de uygulama başlatma ve sonlandırmayı nasıl doğru şekilde ele alacağınızı öğrenin.

Ana Noktalar

  • Not Running — uygulama belleğe yüklenmemiş ve kod çalıştırmıyor; yaşam döngüsünün giriş ve çıkış noktasıdır
  • Başlatma — Not Running’den geçiş, uygulama simgesine dokunma, derin bağlantı veya push bildirimi yoluyla gerçekleşir
  • Sonlandırma — kullanıcı uygulamayı kaydırarak kapatır, sistem bellek yetersizliğinde onu boşaltır veya çökme meydana gelir
  • Soğuk başlatma — uygulama sıfırdan başlar, tüm nesneler yeniden oluşturulur, durum önbellekten geri yüklenmez
  • Sıcak başlatma — uygulama Suspended durumundaydı ve tam başlatma olmadan Active’e döner

Not Running — bu durum nedir

Not Running, bir mobil uygulamanın cihazın RAM’ine yüklenmediği ve sistem kaynaklarını tüketmediği temel yaşam döngüsü durumudur. iOS ve Android’de bu durum, uygulamayla ilişkili işlem ve iş parçacıklarının tamamen yokluğu anlamına gelir. Kullanıcı ana ekranda uygulama simgesini görür, ancak uygulamanın kendisi aktif değildir ve son uygulamalar listesinde yer almaz.

Kullanıcı uygulama simgesine dokunduğunda, sistem yeni bir işlem oluşturur, yürütülebilir kodu belleğe yükler ve gerekli tüm veri yapılarını başlatır. Bu işleme soğuk başlatma (cold start) denir ve yükleme süresi açısından en kaynak yoğun olanıdır.

Sistem, uygulamayı başka herhangi bir durumdan Not Running’e taşıyabilir. Uygulama arka planda veya askıya alınmışsa, işletim sistemi daha yüksek öncelikli görevler için yeterli RAM olmadığında onu boşaltma hakkına sahiptir — örneğin, aktif bir ön plan uygulaması için.

Geliştirici, uygulamanın arka plandayken sistem tarafından her an sonlandırılabileceğini göz önünde bulundurmalıdır. Bu, kaydedilmemiş tüm verilerin kaybolabileceği anlamına gelir. Bu nedenle, Active’den Background’a geçişler sırasında durumu anahtar-değer depolarında (UserDefaults, SharedPreferences) veya yerel bir veritabanında kaydetmek kritik öneme sahiptir.

Sistem hangi uygulamanın boşaltılacağını nasıl belirler

iOS, geçerli uygulama durumuna göre öncelikler kullanır: Active en yüksek önceliğe sahiptir, ardından Inactive, Background, Suspended ve son olarak Not Running — en düşük öncelik. Android benzer bir işlem hiyerarşisi kullanır: Ön plan işleminin önceliği OOM_ADJ = 0, Visible işlemi = 100, Service işlemi = 200, Background işlemi = 300, Empty işlemi = 400. Değer ne kadar yüksekse, bellek azaldığında işlemin sonlandırılma olasılığı o kadar yüksektir.

PlatformDurumBoşaltma önceliğiAçıklama
iOSNot RunningEn yüksekUygulama yüklenmemiş — sistem kaynağı tüketmez
iOSSuspendedYüksekUygulama bellekte ancak kod çalışmıyor — boşaltma için ilk hedef
iOSBackgroundOrtaUygulama arka plan görevi yürütüyor — zaman aşımından sonra boşaltılır
iOSActiveDüşükAktif uygulama — yalnızca kritik bellek baskısı altında boşaltılır
AndroidEmpty ProcessEn yüksekAktif bileşeni olmayan işlem — ilk önce kaldırılır
AndroidBackground ProcessYüksekGörünür Activity’si olmayan arka plan işlemi
AndroidForeground ServiceDüşükBildirimli hizmet — nadiren sonlandırılır
AndroidForeground ProcessMinimumAktif Activity — en son sonlandırılır

Bir uygulamanın soğuk ve sıcak başlatması

Soğuk başlatma (cold start), uygulamanın Not Running’den doğrudan Active’e geçmesiyle gerçekleşir. Sistem yeni bir işlem oluşturur, sınıfları yükler, statik alanları başlatır, ana iş parçacığını oluşturur ve UI çerçevesini başlatır. iOS’te bu, application(_:didFinishLaunchingWithOptions:)’yi çağırmak, Android’de ise Application.onCreate() ve Activity.onCreate()’yi çağırmak anlamına gelir. Soğuk başlatma süresi, uygulamanın karmaşıklığına bağlı olarak 200 ms ile birkaç saniye arasında değişebilir.

Sıcak başlatma (warm start veya hot start) — uygulama Suspended durumundaydı ve tamamen yeniden yükleme olmadan devam eder. Sistem son UI yığınını bellekten geri yükler ve kullanıcı aynı yerden çalışmaya devam eder. Sıcak başlatma, soğuk başlatmadan önemli ölçüde daha hızlıdır çünkü kodun çoğu zaten belleğe yüklenmiştir. iOS’te, sıcak başlatma application(_:didFinishLaunchingWithOptions:)’yi çağırmaz, yalnızca applicationWillEnterForeground ve applicationDidBecomeActive’i çağırır.

Soğuk ve sıcak başlatma arasındaki fark, kullanıcı deneyimi için kritiktir. Soğuk başlatma sırasında geliştirici, başlatmanın mümkün olduğunca hızlı gerçekleşmesini sağlamalıdır — modüllerin tembel başlatılması, ağır kaynakların gecikmeli yüklenmesi, başlatmada ana iş parçacığındaki çalışmanın en aza indirilmesi. Google, soğuk başlatmanın 500 ms’yi, Apple ise iOS için 400 ms’yi geçmemesini önerir.

kotlin
// Android’de soğuk başlatma süresini ölçme
class App : Application() {
    private var startTime: Long = 0L

    override fun onCreate() {
        super.onCreate()
        startTime = System.currentTimeMillis()
    }

    fun getStartupTime(): Long {
        return System.currentTimeMillis() - startTime
    }
}

// Tembel başlatma ile Activity başlatma
class MainActivity : AppCompatActivity() {
    private val viewModel: MainViewModel by lazy {
        ViewModelProvider(this).get(MainViewModel::class.java)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // Yalnızca ilk kare için gerekli minimum
        setupNavigation()
    }

    override fun onPostCreate(savedInstanceState: Bundle?) {
        super.onPostCreate(savedInstanceState)
        // Oluşturmadan sonra ağır başlatma
        initializeHeavyModules()
    }
}

Örnek, Android’de soğuk başlatma süresinin ölçümünü göstermektedir. Application.onCreate(), Not Running’den Active’e geçişte çağrılır. Zaman damgası, işlem başlatıldığında kaydedilir. Activity, ilk kareyi engellememek için bir tembel temsilci aracılığıyla tembel başlatma kullanır. onPostCreate, ağır modülleri başlatmak için en uygun yerdir çünkü UI zaten oluşturulmuştur.

iOS’te Not Running: Swift ve AppDelegate

iOS’te Not Running, UIApplicationDelegate protokolü aracılığıyla yönetilir. Anahtar yöntemler: application(_:didFinishLaunchingWithOptions:) soğuk başlatmadan sonra çağrılır, applicationWillTerminate(_:) kullanıcının uygulamayı sonlandırmasından önce çağrılır. Bununla birlikte, sistem applicationWillTerminate’i çağırmadan uygulamayı sonlandırabilir — örneğin, acil bir sonlandırma veya bellek baskısı sırasında. iOS, bu yöntemin çağrılacağını garanti etmez, bu nedenle veriler applicationDidEnterBackground’da kaydedilmelidir.

iOS’te Not Running’e geçiş senaryoları

Kullanıcı, App Switcher’da kaydırarak uygulamayı manuel olarak sonlandırabilir. Sistem, arka plandayken uygulamayı bellekten boşaltabilir. Uygulama çökebilir. Tüm durumlarda, başlatma sırasında oluşturulan tüm nesneler yok edilir. Kaydedilmeyen durum sonsuza dek kaybolur. iOS 13+ sürümünde, durumu korumak için NSUserActivity veya UIApplication.stateRestorationIdentifier aracılığıyla durum geri yükleme mekanizmasının kullanılması önerilir.

swift
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    // Soğuk başlatma: uygulama Not Running’den geçti
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        // Minimum hizmet setini başlatma
        setupAnalytics()
        configureAppearance()
        return true
    }

    // Uygulama sonlanıyor — yalnızca manuel kapatma
    func applicationWillTerminate(
        _ application: UIApplication
    ) {
        saveCriticalData()
    }

    // Arka plana geçmeden önce verileri kaydetme
    func applicationDidEnterBackground(
        _ application: UIApplication
    ) {
        saveApplicationState()
    }

    private func saveCriticalData() {
        UserDefaults.standard.synchronize()
    }

    private func saveApplicationState() {
        let state = ["lastScreen": "main", "timestamp": Date()]
        try? NSKeyedArchiver.archivedData(
            withRootObject: state,
            requiringSecureCoding: true
        )
    }
}

Kod, iOS’te Not Running’in doğru şekilde ele alınmasını göstermektedir. applicationWillTerminate yalnızca kullanıcı uygulamayı manuel olarak sonlandırdığında çağrılır. Kritik verilerin kaydedilmesi applicationDidEnterBackground’da tekrarlanır çünkü bu yöntemin arka plana geçmeden önce çağrılacağı garanti edilir. Durum geri yükleme, soğuk başlatma sırasında daha sonra kurtarma için UI yığınını kaydetmeye olanak tanır.

Android’de Not Running: Kotlin ve süreç

Android’de Not Running, uygulama işleminin mevcut olmadığı anlamına gelir. Android’in temelini oluşturan Linux sistemi, işlemleri Zygote mekanizması aracılığıyla yönetir. Bir uygulama başlatıldığında, Zygote yeni bir işlem çatalı oluşturur, Dalvik/ART’yi yükler ve Application.onCreate()’yi çağırır. Android’in applicationWillTerminate’in doğrudan bir karşılığı yoktur — sistem, uyarı vermeden işlemi herhangi bir zamanda sonlandırabilir.

Android işlem yaşam döngüsü

Bir Activity ilk kez çağrıldığında, sistem onCreate → onStart → onResume zinciri aracılığıyla işlemi, Application’ı ve Activity’yi oluşturur. Kullanıcı Geri tuşuna basarsa, Activity yok edilir (onDestroy) ve işlem sistem tarafından sonlandırılabilir. iOS’ten önemli bir fark: Android’de işlem, aktif Activity’ler olmasa bile varlığını sürdürebilir — örneğin, bir Foreground Service çalışıyorsa veya aktif bir BroadcastReceiver varsa.

kotlin
// ViewModel’de SavedStateHandle aracılığıyla Not Running’i ele alma
class MainViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {

    companion object {
        private const val KEY_LAST_SCREEN = "last_screen"
        private const val KEY_USER_DATA = "user_data"
    }

    fun saveCurrentState(screen: String, data: String) {
        savedStateHandle[KEY_LAST_SCREEN] = screen
        savedStateHandle[KEY_USER_DATA] = data
    }

    fun restoreState(): AppState? {
        val screen = savedStateHandle.get<String>(KEY_LAST_SCREEN)
        val data = savedStateHandle.get<String>(KEY_USER_DATA)
        return if (screen != null && data != null) {
            AppState(screen, data)
        } else null
    }
}

// Application — Not Running’den sonraki ilk geri çağrı
class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        initCrashReporter()
        initDependencyInjection()
    }
}

SavedStateHandle, Not Running’e geçiş sırasında durumu otomatik olarak kaydeden ve soğuk başlatmada geri yükleyen bir Android Architecture Components bileşenidir. ViewModelProvider aracılığıyla oluşturulan bir ViewModel, ekran döndürme ve Activity yok edilmesinden sağ çıkar. İşlem sonlandırıldığında, SavedStateHandle’daki veriler bir Bundle içinde serileştirilir ve kaydedilmiş örnek durumunda saklanır.

Not Running’e geçiş nedenleri

Not Running birkaç nedenden dolayı gerçekleşir. Kullanıcı uygulamayı manuel olarak kapatır. Sistem, bellek yetersizliği nedeniyle uygulamayı boşaltır. Uygulama bir istisna ile çöker. Android’de sistem, toplu uygulama güncellemesi veya cihaz yeniden başlatması sırasında işlemi sonlandırabilir. iOS, bir arka plan görevinin süresi dolduğunda (genellikle 30 saniye) uygulamayı sonlandırabilir.

NedeniOSAndroidÖnlenebilir mi
Kullanıcı tarafından manuel kapatmaApp Switcher’da kaydırmaRecents’ten kaydırmaHayır — kullanıcı eylemi
Bellek yetersizliğiBellek uyarısı tetiklenmesionTrimMemory / LMKKısmen — bellek optimizasyonu
Uygulama çökmesiNSException / sinyalUncaughtException / ANREvet — hata yönetimi ve çökme raporlaması
Arka plan görevi zaman aşımıArka plan görevi için 30 saniyeJobScheduler için 10 dakikaEvet — doğru görev planlaması
İşletim sistemi yeniden başlatmasıapplicationWillTerminate çağrılırBroadcast ACTION_SHUTDOWNHayır — sistem olayı
Uygulama güncellemesiGerçekleşmez (iOS Sandbox)APK güncellemesinde işlem sonlandırılırHayır — sistem güncellemesi

Not Running’e geçiş nasıl teşhis edilir

iOS için, applicationWillTerminate ve applicationDidFinishLaunching’de konsol günlüğü kullanın. Her başlatmada UserDefaults’a bir işaret ekleyin — işaret bir sonraki başlatmada eksikse, uygulama hatalı bir şekilde sonlandırılmıştır. Android’de, uygulamanın arka plan görevlerini çalıştırıp çalıştıramayacağını kontrol etmek için ActivityManager.isBackgroundRestricted()’yi kullanın. Ayrıca, onTrimMemory(TRIM_MEMORY_COMPLETE)’yi izleyin — bu, işlemin sonlandırılacağına dair bir sinyaldir.

Not Running ile çalışmak için en iyi uygulamalar

İlk kural — applicationWillTerminate veya onDestroy’nin çağrılacağını asla varsaymayın. Active’den Background’a her geçişte kritik derecede önemli verileri kaydedin. Basit ayarlar için anahtar-değer depolarını ve yapılandırılmış veriler için SQLite/Room’u kullanın.

İkinci kural — soğuk başlatma süresini ölçün ve optimize edin. Tembel başlatma, ana iş parçacığındaki çalışmayı en aza indirme, kaynakları önceden yükleme, SplashScreen API’sini kullanma — bunların tümü algılanan başlatma süresini iyileştirir. Google, mükemmel bir kullanıcı deneyimi için soğuk başlatmanın 200 ms’nin altında olmasını önerir.

Üçüncü kural — Durum Geri Yüklemeyi uygulayın. iOS’te UIApplication.stateRestorationIdentifier ve NSUserActivity’yi kullanın. Android’de, onSaveInstanceState ile birleştirilmiş ViewModel’de SavedStateHandle’ı kullanın. Bu, kullanıcının uygulama yeniden başlatıldıktan sonra aynı yerden çalışmaya devam etmesini sağlar.

Dördüncü kural — uygulamanın Not Running’den sonra başlatıldığı launchOptions ve Intent’i ele alın. Derin bağlantılar, push bildirimleri, evrensel bağlantılar — bunların tümü başlatma parametreleri aracılığıyla iletilir. Geliştirici, bu verileri doğru bir şekilde çıkarmalı ve kullanıcıyı ilgili ekrana yönlendirmelidir.

swift
// Soğuk başlatmadan sonra derin bağlantıyı ele alma
func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    // Bildirimin gelip gelmediğini kontrol etme
    if let notification = launchOptions?[.remoteNotification] as? [String: Any] {
        handleNotification(notification)
    }
    // Derin bağlantıyı kontrol etme
    if let url = launchOptions?[.url] as? URL {
        handleDeepLink(url)
    }
    return true
}

private func handleDeepLink(_ url: URL) {
    guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
          let screenId = components.queryItems?.first(where: { $0.name == "screen" })?.value
    else { return }
    openScreen(screenId)
}

Kod, iOS soğuk başlatmasında başlatma parametrelerinin ele alınmasını göstermektedir. launchOptions, sistemin uygulamayı başlattığı verileri içerir. Bildirimler, derin bağlantılar ve evrensel bağlantılar bu sözlük aracılığıyla iletilir. Geliştirici, kesintisiz bir kullanıcı deneyimi sağlamak için tüm olası başlatma senaryolarını doğru bir şekilde ele almalıdır.

Sıkça Sorulan Sorular

Not Running’e geçişte verilere ne olur?

Kalıcı depolamada (UserDefaults, Core Data, SharedPreferences, Room) kaydedilen veriler korunur. RAM’deki veriler — değişkenler, önbellek, SavedStateHandle olmayan ViewModel durumu — geri dönülmez bir şekilde kaybolur. Bu nedenle, her Background’a geçişte uygulama durumunu kaydetmek kritik öneme sahiptir.

iOS’te soğuk başlatmayı sıcak başlatmadan nasıl ayırt edebilirim?

Soğuk başlatma sırasında application(_:didFinishLaunchingWithOptions:) çağrılır. Sıcak başlatma (Suspended’dan dönüş) sırasında bu yöntem çağrılmaz — yalnızca applicationWillEnterForeground ve applicationDidBecomeActive tetiklenir. Yalnızca soğuk başlatmada bir eylem gerçekleştirmeniz gerekiyorsa, didFinishLaunchingWithOptions’da bir işaret ayarlayın.

Bir Android uygulaması aktif bir Service ile Not Running’de olabilir mi?

Evet. Kalıcı bildirime sahip bir Foreground Service, tüm Activities yok edilse bile sistemin işlemi sonlandırmasını engeller. Bir Background Service (foreground olmadan startService), sistem tarafından herhangi bir zamanda durdurulabilir. Çalışan bir Service, işlemin var olduğu anlamına gelir ve bu artık Not Running değildir.

Bir simülatörde Not Running nasıl simüle edilir?

iOS simülatöründe, uygulamayı App Switcher (Cmd+Shift+H iki kez, yukarı kaydırma) aracılığıyla sonlandırın. Android emülatöründe, adb shell am force-stop com.example.app veya Logcat’teki Stop düğmesini kullanın. Bundan sonra uygulamayı tekrar başlatın — bu, Not Running’den temiz bir soğuk başlatma olacaktır.

Not Running bağlamında kill-switch nedir?

Kill-switch, acil uygulama sonlandırması için bir sunucu komutudur. Bankacılık ve kurumsal uygulamalarda uzaktan erişim engellemesi için kullanılır. Uygulama bir kill komutu alırsa, bir sonraki soğuk başlatmada UI’yı bloke eder ve yeniden kimlik doğrulaması ister. iOS’te kill-switch, engelleme işaretli uzak bildirimler aracılığıyla uygulanır.

Özet

  • Not Running — yaşam döngüsünün başlangıç ve son durumu, uygulama belleğe yüklenmemiş ve kod çalıştırmıyor
  • Soğuk başlatma — uygulamanın Not Running’den tamamen yeniden başlatılması, tüm bileşenlerin sıfırdan başlatılmasını gerektirir
  • Sıcak başlatma — Suspended’dan dönüş, didFinishLaunchingWithOptions veya Application.onCreate’i çağırmaz
  • Veri kaydetme — Background’a geçişte yapılması kritik öneme sahiptir, çünkü Not Running her an gerçekleşebilir
  • iOS — applicationWillTerminate garanti edilmez, durum UserDefaults veya durum geri yükleme yoluyla kaydedilir
  • Android — işlem her an sonlandırılabilir, ViewModel’deki SavedStateHandle durumu otomatik olarak kaydeder
  • Başlatma optimizasyonu — tembel başlatma, ana iş parçacığında minimum çalışma, hızlı ilk kare için SplashScreen API

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.

Projeyi tartış

Ayrıca okuyun