onPause: nedir, Android'de Activity durumunu kaydetme

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

onPause, bir Activity giriş odağını kaybettiğinde ancak ekranda kısmen görünür kaldığında çağrılan bir Android yaşam döngüsü yöntemidir. Sistem, yeni bir Activity ön plana çıkmadan önce, bir iletişim kutusu açıldığında, Son Uygulamalar düğmesine basıldığında veya gelen bir arama olduğunda onPause'u çağırır. Bu yöntem, kullanıcı verilerini kaydetmek için son garantili noktadır, çünkü onStop ve onDestroy'den sonra sistem ek çağrı olmadan işlemi sonlandırabilir. onPause içinde geliştirici taslakları kaydeder, animasyonları duraklatır, kamerayı serbest bırakır ve geçerli UI durumunu SharedPreferences'a yazar. Tam Activity yaşam döngüsü hakkında daha fazla ayrıntı için Activity Lifecycle makalesini okuyun.

Önemli Noktalar

  • onPause — Activity odağı kaybeder ancak görünür kalır; veri kaydetmek için son garantili nokta
  • Durum Kaydetme — onPause'da kritik kullanıcı verileri kaydedilir: taslaklar, form metni, ilerleme
  • Kaynakları Serbest Bırakma — kamera, mikrofon, video oynatıcı onPause'da başka bir uygulamaya aktarılmak üzere serbest bırakılır
  • Süre Sınırı — onPause 100 ms içinde tamamlanmalıdır; aşılması ANR'ye neden olur ve geçişi geciktirir
  • SharedPreferences.apply() — onPause'da async yazma; commit() iş parçacığını bloke eder ve ANR'ye neden olabilir
  • onPause vs onStop — onPause kısmi görünürlükte (iletişim kutusu), onStop tam gizlenmede (başka Activity)
  • onSaveInstanceState — onPause'dan sonra geçici durumu Bundle'da kaydetmek için çağrılır

Android'de onPause Nedir

onPause, Activity yaşam döngüsünün dördüncü yöntemidir ve ekran giriş odağını kaybettiğinde ancak kullanıcıya kısmen görünür kaldığında çağrılır. Uygulamanın aktif olarak çalışması ile gizlenmesi arasında bir «geçiş» durumudur. Sistem onPause'u şu senaryolarda çağırır: başka bir Activity açılması (yeni bir ekran mevcut ekranı kısmen kaplar), bir iletişim kutusu penceresinin görünmesi (Dialog, PopupWindow, Snackbar onPause'u tetiklemez, ancak DialogFragment tetikler), Son Uygulamalar düğmesine basılması, gelen arama, ekranı kilitlemek için güç düğmesine basılması.

onPause'un ana görevi, uygulamayı gizlenme veya yok edilme olasılığına hazırlamaktır. Bu, geliştiricinin sistem başka bir bileşene geçiş yapmadan önce kodunun çalıştırılacağından emin olabileceği yaşam döngüsündeki son noktadır. onPause'dan sonra sistem onStop'u çağırır (Activity tamamen gizlenmişse), ardından işlem ek bildirim olmadan herhangi bir zamanda sonlandırılabilir.

Android Developers belgelerine (2025) göre, onPause mümkün olduğunca hafif ve hızlı olmalıdır. onPause kontrolü geri verene kadar sistem sonraki Activity'i başlatamaz — bu, kullanıcının ekran geçişinde gecikme gördüğü anlamına gelir. Google, onPause'un 100 milisaniyeden az sürede tamamlanmasını önerir ve tüm uzun işlemler (veritabanına kaydetme, diske yazma) eşzamansız olarak coroutines veya apply() aracılığıyla yapılmalıdır.

Activity'de onPause

Bir Activity'de, onPause yöntemi ekran artık aktif olmadığında ancak kısmen görüntülenmeye devam edebildiğinde her seferinde çağrılır. Tipik bir örnek: kullanıcı Haritalar uygulamasını açar, Konumu Paylaş'a dokunur ve Haritalar'ın üzerinde bir sistem uygulama seçimi iletişim kutusu belirir. Haritalar Activity'si onPause alır ancak iletişim kutusunun altında görünür kalır. İletişim kutusu kapatıldığında, Haritalar onStart çağrılmadan onResume alır (ekran tamamen gizlenmemiştir).

kotlin
class NoteEditorActivity : AppCompatActivity() {
    private var binding: ActivityNoteEditorBinding? = null
    private val prefs by lazy {
        getSharedPreferences("note_drafts", Context.MODE_PRIVATE)
    }

    override fun onPause() {
        super.onPause()

        // Not taslağını kaydet — async
        prefs.edit()
            .putString("draft_title", binding?.titleInput?.text.toString())
            .putString("draft_body", binding?.bodyInput?.text.toString())
            .putLong("draft_timestamp", System.currentTimeMillis())
            .apply()

        // Videoyu duraklat
        binding?.videoPlayer?.pause()

        // Özel kaynakları serbest bırak
        releaseCamera()
        releaseAudioFocus()
    }

    override fun onResume() {
        super.onResume()
        // Taslağı geri yükle
        binding?.titleInput?.setText(prefs.getString("draft_title", ""))
        binding?.bodyInput?.setText(prefs.getString("draft_body", ""))
        acquireCamera()
        acquireAudioFocus()
    }
}

NoteEditorActivity örneği, onPause'un doğru şekilde işlenmesini gösterir: apply() aracılığıyla SharedPreferences'a taslak kaydetme, video dosyasını duraklatma, kamerayı ve ses odağını serbest bırakma. Her çağrı hafif ve hızlıdır, ANR'yi tetikleyecek kadar UI iş parçacığını bloke etmez. Sıraya dikkat edin: super.onPause() ilk satırda çağrılır — bu, kullanıcı kodunda bir istisna olsa bile sistem mantığının çalışmasını garanti eder.

onPause'da Durum Kaydetme

onPause, uygulama gizlenmeden veya sistem tarafından sonlandırılmadan önce geliştiricinin kullanıcı verilerini güvenilir bir şekilde kaydedebileceği son noktadır. onStop'dan sonra sistem, bellek yetersizse onDestroy'u çağırmadan işlemi sonlandırabilir. onSaveInstanceState() yöntemi onPause'dan sonra çağrılır, ancak Bundle'ı uzun süreli depolama için tasarlanmamıştır — yalnızca sonraki onCreate'e kadar yaşar.

apply() ile SharedPreferences

Async apply() ile SharedPreferences, onPause'da küçük miktarlarda veri kaydetmenin optimal yoludur commit()'in aksine, verileri senkron olarak diske yazan ve boolean döndüren, apply() verileri hemen belleğe kaydeder ve async disk yazmasını planlar. Bu, commit()'in 10–100 milisaniyesine karşı UI iş parçacığında 1 milisaniyeden az sürer.

kotlin
override fun onPause() {
    super.onPause()

    // ❌ Kötü: senkron yazma iş parçacığını bloke eder
    // prefs.edit().putInt("score", score).commit()

    // ✅ İyi: async yazma
    prefs.edit().putInt("score", score).apply()

    // Karmaşık nesneler için — ViewModel'de önbelleğe alma
    viewModel.saveState()
}

Room ve Coroutines

onPause'da yapılandırılmış veriler (Room aracılığıyla SQLite) için lifecycleScope ile coroutines kullanılır. ViewModelScope, ViewModel yok edildiğinde coroutine'i otomatik olarak iptal eder ve kapalı bir veritabanına yazmayı önler. Coroutines ile Room aracılığıyla yazma 5–15 milisaniye sürer ve UI iş parçacığını bloke etmez.

kotlin
// ViewModel'de:
fun saveDraft(title: String, body: String) {
    viewModelScope.launch(Dispatchers.IO) {
        noteDao.insert(NoteDraft(title = title, body = body))
    }
}

// Activity.onPause'da:
viewModel.saveDraft(
    binding?.titleInput?.text.toString(),
    binding?.bodyInput?.text.toString()
)

Fragment'te onPause

Fragment'te onPause, Fragment artık aktif olmadığında ancak görünür kalabildiğinde çağrılır. Bu şu durumlarda olur: bir Fragment, FragmentTransaction aracılığıyla başka bir Fragment ile değiştirildiğinde; bir Fragment, ViewPager'da geçerli sayfa olmaktan çıktığında; Fragment'i içeren Activity onPause aldığında. Activity onPause ile Fragment onPause arasındaki etkileşim kesinlikle hiyerarşiktir: önce Activity onPause alır, ardından tüm Fragment'leri alır.

kotlin
class MapFragment : Fragment() {
    private var mapController: MapController? = null

    override fun onPause() {
        super.onPause()
        mapController?.stopFollowMode()
        binding?.mapContainer?.alpha = 0.7f
    }

    override fun onResume() {
        super.onResume()
        binding?.mapContainer?.alpha = 1.0f
        if (isVisible) {
            mapController?.startFollowMode()
        }
    }
}

onPause'da haritalarla çalışmanın özellikleri: Google Maps ve Yandex Maps, aktif takip modunda önemli GPU kaynakları tüketir. Odak kaybedildiğinde, harita animasyonunu devre dışı bırakmak ve işaretçi güncelleme sıklığını azaltmak mantıklıdır ve odak geri geldiğinde tam işlevselliği geri yüklemek gerekir. Bu, ekranlar arasında geçiş yaparken performansı artırır ve güç tüketimini azaltır.

onPause vs onStop: Fark ve Senaryolar

Yeni başlayan Android geliştiricileri arasındaki en yaygın kafa karışıklıklarından biri, onPause ve onStop arasındaki farkı anlamamaktır. Her senaryoyu inceleyelim ve doğru yöntemi belirleyelim.

SenaryoonPauseonStop
İletişim kutusu penceresi açmaÇağrılırÇağrılmaz
Yeni Activity açma (saydam olmayan)ÇağrılırÇağrılır
Ana Ekran düğmesine basmaÇağrılırÇağrılır
Ekran kilidiÇağrılırÇağrılır
Gelen aramaÇağrılırÇağrılır
Üstte saydam ActivityÇağrılırÇağrılmaz
Bölünmüş Ekran (yarım ekran)ÇağrılırÇağrılmaz
PiP (Resim İçinde Resim)ÇağrılırÇağrılmaz

Ana kural: onPause herhangi bir odak kaybında çağrılır, onStop yalnızca görünürlük tamamen kaybolduğunda çağrılır. Activity görünür kalırsa (kısmen bile olsa), onStop çağrılmaz. Bu, Bölünmüş Ekran, PiP ve saydam Activity modları için kritik öneme sahiptir — burada onPause/onResume çalışır, ancak onStart/onStop çalışmaz.

onPause Zamanlaması ve Performansı

onPause, sonraki Activity'nin işlenmesini bloke ettiği için zaman açısından en kritik yaşam döngüsü yöntemidir. Sistem, yenisini göstermeden önce mevcut Activity'nin onPause'unun tamamlanmasını bekler. onPause 100 milisaniyeden uzun sürerse, kullanıcı geçişte gecikme fark eder; 5 saniyeden uzun sürerse sistem ANR gösterir.

Performans Önerileri

Google Android Performans Kılavuzu (2025), onPause için aşağıdaki önerileri sunar: ağ istekleri yapmayın — iptal edilmeli veya WorkManager'a taşınmalıdır; diske büyük dosyalar yazmayın — arka plan iş parçacığında BufferedWriter kullanın; karmaşık SQL sorguları çalıştırmayın — Room işlemleri coroutines aracılığıyla async olmalıdır; yeni nesneler oluşturmaktan kaçının — onPause'da çöp toplama gecikmeyi kötüleştirir; SharedPreferences için commit() yerine apply() kullanın.

kotlin
override fun onPause() {
    super.onPause()

    // ❌ Kötü: HTTP isteği UI'yı bloke eder
    // val response = api.syncSave(data).execute()

    // ❌ Kötü: dosyaya senkron yazma
    // FileOutputStream(file).write(data)

    // ✅ İyi: async kaydetme
    lifecycleScope.launch {
        withContext(Dispatchers.IO) {
            api.saveData(data)
            fileDao.write(data)
        }
    }

    // ✅ İyi: SharedPreferences'a hafif yazma
    prefs.edit().putString("key", value).apply()
}

Android Studio Profiler (CPU izi) aracılığıyla onPause profil oluşturma, tam yürütme süresini gösterir. onPause 100 ms'den uzun sürerse, Profiler yöntemi sarı renkle vurgular ve 500 ms'den uzunsa kırmızıyla. IT Sectr'daki ticari projelerde, Activity'ler arasındaki geçiş süresini otomatik olarak kontrol eden ve CI hattındaki performans düşüşlerini bildiren Macrobenchmark testleri kullanıyoruz.

onPause'da Sık Yapılan Hatalar

Deneyimli geliştiriciler bile onPause'da hatalar yapar. Beş tipik sorunu ve çözümlerini inceleyelim.

Senkron Veritabanı Yazma

onPause'da senkron sorgu (.executeAsObservable() coroutines olmadan) ile Room DAO çağırmak UI iş parçacığını 10–50 ms boyunca bloke eder. Aynı anda GC veya yazma çekişmesi olursa, gecikme 200–500 ms'ye ulaşabilir. Çözüm: Dispatchers.IO ile coroutines veya SharedPreferences için apply() kullanın.

Yeni Dinleyici Kaydetme

onPause, dinleyici kaydetmek için yer değildir. onPause'da bir BroadcastReceiver kaydederseniz, Activity artık görünür olmadığında bile etkin kalır. Kayıt yalnızca onStart/onResume'da yapılmalı ve onPause/onStop'da yalnızca kaydı iptal etme yapılmalıdır. İstisna, çağrıdan önce kayıt gerektiren Intent tabanlı API'lerdir.

İstisnaları Görmezden Gelme

onPause'da işlenmeyen bir istisna oluşursa, sistem onStop ve onDestroy'u çağırmaz. Activity tanımsız bir durumda takılıp kalır ve geri dönüşte onResume, serbest bırakılan kaynakları doğru şekilde geri yüklemeyebilir. Çözüm: kritik işlemleri Log.e() ile günlüğe kaydetmeyle birlikte try/catch içine alın.

Gereksiz Veri Kaydetme

Kolayca geri yüklenebilen verileri onPause'da kaydetmeye gerek yoktur. Örneğin, API istek sonuçları onPause'da değil, alınma anında Room veya DataStore'da önbelleğe alınır. Yalnızca kullanıcının manuel olarak girdiği ve otomatik olarak geri yüklenemeyenleri kaydedin — alanlardaki metin, seçilen öğeler, kaydırma konumu.

super.onPause()'u Unutma

super.onPause() çağrılmalıdır, ancak onCreate'in aksine, atlanması hemen çökmeye neden olmaz. Sistem, onPause'da super'in eksikliğini «affeder», ancak iç durum makinesi yanlış bir duruma girer. Sonraki onResume çağrısı giriş odağını geri yüklemeyebilir ve Activity «donmuş» kalır. Her zaman super.onPause()'u mümkün olduğunca erken çağırın.

Sıkça Sorulan Sorular

onPause'da finish() çağrılırsa ne olur?

onPause'da finish() çağırmak, yöntemden döndükten hemen sonra Activity'yi sonlandırır. Bu, odak kaybedildiğinde ekranın kapatılması gerekiyorsa (örneğin, uygulama simge durumuna küçültüldüğünde yetkilendirme ekranı) geçerli bir senaryodur. Ancak, finish() tam sonlandırma döngüsünü tetikler: onStop onDestroy, bu da geçişe gecikme ekler. onPause'da finish()'i yalnızca gerçekten gerekli olduğunda kullanın.

onPause, onSaveInstanceState'dan nasıl farklıdır?

onPause, işlem sonlandırmasından sonra hayatta kalması gereken verileri kaydetmek içindir (SharedPreferences/Room'daki taslaklar). onSaveInstanceState, yalnızca sonraki onCreate'e kadar gereken geçici UI durumunu kaydetmek içindir (kaydırma konumu, seçili sekme). onSaveInstanceState Bundle'ı uygulama tamamen sonlandırıldığında korunmaz — yalnızca bellekte bulunur. onPause verileri diske kaydedilir ve yeniden başlatmadan sonra hayatta kalır.

onPause'da iletişim kutusu açılabilir mi?

Önerilmez. onPause'da bir iletişim kutusu veya açılır pencere açmak, Activity zaten sonlandırılmışsa WindowLeakException'a neden olur. Odak kaybedildiğinde bir bildirim göstermeniz gerekiyorsa, NotificationManager'ı (sistem bildirimleri) kullanın — bu güvenlidir ve kullanıcı tarafından beklenir. Ertelenmiş eylemler için AlarmManager veya WorkManager kullanın.

Neden onPause garantili bir kaydetme noktasıyken onStop değil?

onPause'un Activity aktif olmayı bırakmadan önce çağrılması garantilidir Sistem belleği boşaltmak için işlemi öldürürse onStop çağrılmayabilir — bu durumda onDestroy da çağrılmaz. onPause, onResume'dan sonra odak kaybının nedeni ne olursa olsun her zaman çağrılan tek yöntemdir. Bu nedenle, tüm kritik veriler tam olarak onPause'da kaydedilir.

Birim testlerde onPause nasıl test edilir?

onPause'u test etmek için Robolectric veya AndroidX Test'ten FragmentScenario kullanılır. FragmentScenario.create() moveToState(State.STARTED) moveToState(State.RESUMED) moveToState(State.STARTED) sırayla onPause'u çağırır. Ardından, verilerin SharedPreferences'a kaydedildiği veya kameranın bir mock nesnesi aracılığıyla serbest bırakıldığı doğrulanır. Robolectric 4.12+, fiziksel bir cihaz olmadan onPause/onResume öykünmesini destekler.

Özet

  • onPause — Activity giriş odağını kaybeder ancak kısmen görünür kalır; veri kaydetmek için son garantili nokta
  • Kaydetme — SharedPreferences.apply() veya coroutines aracılığıyla Room; commit() ve senkron işlemler yasaktır
  • Kaynak Serbest Bırakma — kamera, ses odağı, video oynatıcı onPause'da başka bir uygulamaya aktarılmak üzere serbest bırakılır
  • 100 ms Sınırı — onPause sonraki Activity'nin işlenmesini bloke eder; sınırın aşılması ANR'ye neden olur
  • onPause vs onStop — onPause odak kaybında (görünürlük korunur), onStop tam gizlenmede
  • Fragment.onPause — Activity.onPause'dan sonra hiyerarşik çağrı; haritalar ve ViewPager için özellikler
  • Sık Yapılan Hatalar — senkron yazma, dinleyici kaydetme, try/catch'i görmezden gelme, gereksiz kaydetme
  • super.onPause() — mümkün olduğunca erken çağırın; atlanması çökmez ancak durum makinesini bozar

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