onPause: bu nədir, Android-də Activity vəziyyətinin saxlanması

Müəllif: IT Sectr Dərc olunub: 2026-03-04 Oxuma vaxtı: 10 dəq

onPause — Android həyat dövrü metodudur ki, Activity daxiletmə fokusunu itirdikdə, lakin ekranda qismən görünən qaldıqda çağırılır. Sistem onPause-u yeni Activity ön plana çıxmamışdan əvvəl, dialoq pəncərəsi açıldıqda, “Son proqramlar” düyməsi basıldıqda və ya zəng gəldikdə çağırır. Bu metod — istifadəçi məlumatlarını saxlamaq üçün son zəmanətli nöqtədir, çünki onStop və onDestroy-dan sonra sistem əlavə çağırışlar olmadan prosesi bağlaya bilər. onPause daxilində tərtibatçı qaralamaları saxlayır, animasiyaları dayandırır, kameranı boşaldır və cari UI vəziyyətini SharedPreferences-də yazır. Activity-nin tam həyat dövrü haqqında ətraflı Activity Lifecycle məqaləsində oxuyun.

Əsas məqamlar

  • onPause — Activity fokusu itirir, lakin görünən qalır; məlumatların saxlanması üçün son zəmanətli nöqtə
  • Vəziyyətin saxlanması — onPause-da istifadəçinin kritik məlumatları saxlanılır: qaralamalar, formalardakı mətn, irəliləyiş
  • Resursların boşaldılması — kamera, mikrofon, video pleyer onPause-da başqa proqrama ötürmək üçün boşaldılır
  • Vaxt limiti — onPause 100 ms ərzində bitməlidir; aşma ANR-yə səbəb olur və keçidi gecikdirir
  • SharedPreferences.apply() — onPause-da asinxron yazma; commit() axını bloklayır və ANR-yə səbəb ola bilər
  • onPause vs onStop — onPause qismən görünmədə (dialoq), onStop tam gizlənmədə (digər Activity)
  • onSaveInstanceState — Bundle-də müvəqqəti vəziyyəti saxlamaq üçün onPause-dan sonra çağırılır

Android-də onPause nədir

onPause — Activity həyat dövrünün dördüncü metodudur ki, ekran daxiletmə fokusunu itirdikdə, lakin istifadəçi üçün qismən görünən qaldıqda çağırılır. Bu, proqramın aktiv işi ilə onun gizlədilməsi arasında “keçid” vəziyyətidir. Sistem onPause-u aşağıdakı ssenarilərdə çağırır: başqa Activity-nin açılması (yeni ekran cari ekranı örtür), dialoq pəncərəsinin görünməsi (Dialog, PopupWindow, Snackbar onPause çağırmır, DialogFragment isə çağırır), “Son proqramlar” düyməsinin basılması, zəng gəlməsi, ekranı bloklamaq üçün “Güc” düyməsinin basılması.

onPause-un əsas vəzifəsi proqramı gizlənə və ya məhv edilə biləcəyi vəziyyətə hazırlamaqdır. Bu, tərtibatçının kodunun sistem başqa komponentə keçməzdən əvvəl icra olunacağına əmin ola biləcəyi həyat dövründəki son nöqtədir. onPause-dan sonra sistem onStop-u çağırır (Activity tam gizlənirsə), ondan sonra prosesin məhv edilməsi əlavə bildiriş olmadan istənilən vaxt baş verə bilər.

Android Developers (2025) sənədlərinə görə, onPause maksimum yüngül və sürətli olmalıdır. onPause idarəetməni qaytarmayana qədər sistem növbəti Activity-ni işə sala bilməz — bu o deməkdir ki, istifadəçi ekranlar arasında keçid gecikməsi görür. Google onPause-u 100 millisaniyədən az müddətdə bitirməyi və bütün uzunmüddətli əməliyyatları (verilənlər bazasına yazma, diskə yazma) korutinlər və ya apply() vasitəsilə asinxron yerinə yetirməyi tövsiyə edir.

Activity-də onPause

Activity-də onPause metodu hər dəfə ekran aktiv olmağı dayandırdıqda, lakin qismən göstərilməyə davam edə bildikdə çağırılır. Tipik nümunə: istifadəçi “Xəritələr” proqramını açır, “Məkanı paylaş” düyməsini basır və Xəritələrin üzərində sistem proqram seçimi dialoqu açılır. Xəritələr Activity-si onPause alır, lakin dialoqun altında görünən qalır. Dialoq bağlandıqda, Xəritələr onStart çağırılmadan onResume alır (ekran tam gizlənməyib).

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()

        // Qaralamanı qeyd edirik — asinxron
        prefs.edit()
            .putString("draft_title", binding?.titleInput?.text.toString())
            .putString("draft_body", binding?.bodyInput?.text.toString())
            .putLong("draft_timestamp", System.currentTimeMillis())
            .apply()

        // Videonu dayandırırıq
        binding?.videoPlayer?.pause()

        // Eksklüziv resursları boşaldırıq
        releaseCamera()
        releaseAudioFocus()
    }

    override fun onResume() {
        super.onResume()
        // Qaralamanı bərpa edirik
        binding?.titleInput?.setText(prefs.getString("draft_title", ""))
        binding?.bodyInput?.setText(prefs.getString("draft_body", ""))
        acquireCamera()
        acquireAudioFocus()
    }
}

NoteEditorActivity nümunəsi onPause ilə düzgün işi nümayiş etdirir: SharedPreferences-də apply() vasitəsilə qaralamanın saxlanması, video faylının dayandırılması, kameranın və audio fokusun boşaldılması. Hər çağırış yüngül və sürətlidir, UI axınını ANR üçün kifayət edəcək qədər bloklamır. Sıraya diqqət yetirin: super.onPause() birinci sətirdə çağırılır — bu, istifadəçi kodunda istisna olsa belə sistem məntiqinin icrasını təmin edir.

onPause-da vəziyyətin saxlanması

onPause — tərtibatçının proqram gizlədilməzdən və ya sistem tərəfindən bağlanmazdan əvvəl istifadəçi məlumatlarını zəmanətlə saxlaya biləcəyi son nöqtədir. onStop-dan sonra sistem yaddaş çatışmazlığında onDestroy çağırmadan prosesi məhv edə bilər. onSaveInstanceState() metodu onPause-dan sonra çağırılır, lakin onun Bundle-i uzunmüddətli saxlama üçün nəzərdə tutulmayıb — yalnız növbəti onCreate-ə qədər yaşayır.

SharedPreferences apply() ilə

Asinxron apply() ilə SharedPreferences — onPause-da kiçik həcmli məlumatların saxlanması üçün optimal üsuldur. commit() ilə müqayisədə, sinxron olaraq diskə yazan və boolean qaytaran, apply() dərhal yaddaşa yazır və diskə asinxron yazmanı planlaşdırır. Bu, commit()-in 10–100 millisaniyəsinə qarşı UI axınında 1 millisaniyədən az vaxt aparır.

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

    // ❌ Pis: sinxron yazma axını bloklayır
    // prefs.edit().putInt("score", score).commit()

    // ✅ Yaxşı: asinxron yazma
    prefs.edit().putInt("score", score).apply()

    // Mürəkkəb obyektlər üçün — ViewModel-də keşləmə
    viewModel.saveState()
}

Room və korutinlər

Strukturlaşdırılmış məlumatlar üçün (Room vasitəsilə SQLite) onPause-da lifecycleScope ilə korutinlərdən istifadə olunur. ViewModelScope ViewModel məhv edildikdə korutini avtomatik ləğv edir, bu da bağlı verilənlər bazasına yazmanın qarşısını alır. Room ilə korutinlərlə yazma 5–15 millisaniyə çəkir və UI axınını bloklamır.

kotlin
// ViewModel-də:
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-də onPause

Fragment-də onPause Fragment aktiv olmağı dayandırdıqda, lakin görünən qala bildikdə çağırılır. Bu, aşağıdakı hallarda baş verir: Fragment FragmentTransaction vasitəsilə başqa Fragment ilə əvəz edildikdə; Fragment ViewPager-da cari səhifə olmağı dayandırdıqda; Fragmenti ehtiva edən Activity onPause aldıqda. Activity-nin onPause-u ilə Fragment-in onPause-u arasında qarşılıqlı əlaqə ciddi iyerarxikdir: əvvəlcə onPause-u Activity alır, sonra onun bütün Fragmentləri.

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()
        }
    }
}

Xəritələrlə onPause-da işin spesifikası: Google Maps və Yandex Maps aktiv izləmə rejimində (follow mode) əhəmiyyətli GPU resursları istehlak edir. Fokus itirildikdə xəritə animasiyasını söndürmək və markerlərin yenilənmə tezliyini azaltmaq, fokus qayıtdıqda isə tam funksionallığı bərpa etmək məntiqlidir. Bu, ekranlar arasında keçid zamanı performansı yaxşılaşdırır və enerji istehlakını azaldır.

onPause vs onStop: fərq və ssenarilər

Başlayan Android tərtibatçıları arasında ən çox qarışıqlıq onPause və onStop arasındakı fərqi anlamamaqdır. Hər ssenarini nəzərdən keçirək və düzgün metodu müəyyən edək.

SsenarionPauseonStop
Dialoq pəncərəsinin açılmasıÇağırılırÇağırılmır
Yeni Activity-nin açılması (şəffaf deyil)ÇağırılırÇağırılır
“Ev” düyməsinin basılmasıÇağırılırÇağırılır
Ekranın bloklanmasıÇağırılırÇağırılır
Zəng gəlməsiÇağırılırÇağırılır
Cari üzərində şəffaf ActivityÇağırılırÇağırılmır
Split Screen (ekranın yarısı)ÇağırılırÇağırılmır
PiP (Picture-in-Picture)ÇağırılırÇağırılmır

Əsas qayda: onPause hər fokus itkisində çağırılır, onStop — yalnız tam görünmə itkisində. Activity görünən qalırsa (hətta qismən), onStop çağırılmır. Bu, Split Screen, PiP və şəffaf Activity rejimləri üçün kritikdir — burada onPause/onResume işləyir, onStart/onStop isə işləmir.

onPause vaxtı və performansı

onPause — həyat dövrünün vaxt baxımından ən kritik metodudur, çünki növbəti Activity-nin render edilməsini bloklayır. Sistem yeni Activity-ni göstərməzdən əvvəl cari Activity-nin onPause-unun bitməsini gözləyir. onPause 100 millisaniyədən çox çəkərsə, istifadəçi keçid gecikməsini görür; 5 saniyədən çox olarsa — sistem ANR göstərir.

Performans tövsiyələri

Google Android Performance Guide (2025) onPause üçün aşağıdakı tövsiyələri verir: şəbəkə sorğuları yerinə yetirməyin — onlar ləğv edilməli və ya WorkManager-ə köçürülməlidir; böyük faylları diskə yazmayın — fon axınında BufferedWriter istifadə edin; mürəkkəb SQL sorğuları yerinə yetirməyin — Room əməliyyatları korutinlər vasitəsilə asinxron olmalıdır; yeni obyektlər yaratmaqdan çəkinin — onPause-da garbage collection gecikməni daha da artırır; SharedPreferences üçün commit() əvəzinə apply() istifadə edin.

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

    // ❌ Pis: HTTP sorğusu UI-ni bloklayır
    // val response = api.syncSave(data).execute()

    // ❌ Pis: fayla sinxron yazma
    // FileOutputStream(file).write(data)

    // ✅ Yaxşı: asinxron saxlama
    lifecycleScope.launch {
        withContext(Dispatchers.IO) {
            api.saveData(data)
            fileDao.write(data)
        }
    }

    // ✅ Yaxşı: SharedPreferences-ə yüngül yazma
    prefs.edit().putString("key", value).apply()
}

Android Studio Profiler (CPU qrafiki) vasitəsilə onPause-un profilləşdirilməsi dəqiq icra müddətini göstərir. onPause 100 ms-dən çox çəkərsə, Profiler metodu sarı, 500 ms-dən çox çəkərsə — qırmızı rənglə vurğulayır. IT Sectr kommersiya layihələrində Activity-lər arasında keçid vaxtını avtomatik yoxlayan və CI pipeline-da performans reqressiyası barədə xəbərdarlıq edən Macrobenchmark testlərindən istifadə edirik.

onPause-da tez-tez buraxılan səhvlər

Təcrübəli tərtibatçılar da onPause-da səhvlərə yol verir. Beş tipik problemi və onların həllərini nəzərdən keçirək.

Verilənlər bazasına sinxron yazma

onPause-da sinxron sorğu ilə Room DAO-nun çağırılması (.executeAsObservable() korutinsiz) UI axınını 10–50 ms bloklayır. Əgər bu anda GC və ya verilənlər bazasına yazma üçün rəqabət olarsa, gecikmə 200–500 ms-ə çata bilər. Həll yolu: Dispatchers.IO ilə korutinlərdən və ya SharedPreferences üçün apply() istifadə edin.

Yeni dinləyicilərin qeydiyyatı

onPause dinləyicilərin qeydiyyatı üçün yer deyil. onPause-da BroadcastReceiver qeydiyyatdan keçirsəniz, Activity artıq görünmədikdə belə aktiv qalacaq. Qeydiyyat yalnız onStart/onResume-də, onPause/onStop-da isə yalnız qeydiyyatdan çıxarma olmalıdır. İstisna — çağırışdan əvvəl qeydiyyat tələb edən Intent-driven API-lərdir.

İstisnaların nəzərə alınmaması

onPause-da işlənməmiş istisna baş verərsə, sistem onStop və onDestroy çağırmır. Activity qeyri-müəyyən vəziyyətdə donur və qayıtdıqda onResume düzgün boşaldılmış resursları bərpa edə bilməz. Həll yolu: kritik əməliyyatları Log.e() ilə loqlama ilə try/catch ilə əhatə edin.

Həddindən artıq məlumatların saxlanması

onPause-da asanlıqla bərpa oluna bilən məlumatları saxlamağa ehtiyac yoxdur. Məsələn, API sorğularının nəticələri onPause-da deyil, alındığı anda Room və ya DataStore-da keşlənir. Yalnız istifadəçinin əl ilə daxil etdiyi və avtomatik bərpa edə bilməyəcəyi məlumatları saxlayın — sahələrdəki mətn, seçilmiş elementlər, scroll mövqeyi.

super.onPause() unudulub

super.onPause() çağırılmalıdır, lakin onCreate-dən fərqli olaraq, onun olmaması dərhal crash-a səbəb olmur. Sistem onPause-da super-in buraxılmasını “bağışlayır”, lakin daxili vəziyyət maşını yanlış vəziyyətə keçir. Növbəti onResume çağırışı daxiletmə fokusunu bərpa edə bilməz və Activity “donmuş” qalır. Həmişə super.onPause()-u mümkün qədər tez çağırın.

Tez-tez verilən suallar

onPause-da finish() çağırılsa nə olar?

onPause-da finish() çağırışı Activity-ni metoddan qayıtdıqdan dərhal sonra başa çatdıracaq. Bu, fokus itirildikdə ekranı bağlamaq tələb olunarsa düzgün ssenaridir (məsələn, proqram minimuma endirildikdə avtorizasiya ekranı). Lakin finish() tam bağlanma dövrünü işə salır: onStop → onDestroy, bu da keçidə gecikmə əlavə edir. finish()-i onPause-da yalnız həqiqətən zəruri olduqda istifadə edin.

onPause onSaveInstanceState-dan nə ilə fərqlənir?

onPause — prosesin başa çatmasından sonra da qalmalı olan məlumatların saxlanması üçündür (SharedPreferences/Room-da qaralamalar). onSaveInstanceState — yalnız növbəti onCreate-ə qədər lazım olan müvəqqəti UI vəziyyətinin saxlanması üçündür (scroll mövqeyi, seçilmiş tab). onSaveInstanceState Bundle-i proqram tam bağlandıqda saxlanmır — yalnız yaddaşda mövcuddur. onPause məlumatları diskdə saxlanılır və yenidən başlatmanı da qaldırır.

onPause-da dialoq pəncərəsi açmaq olarmı?

Tövsiyə edilmir. onPause-da dialoq və ya açılan pəncərənin açılması WindowLeakException-a səbəb olur, əgər Activity artıq başa çatıbsa. Fokus itirildikdə bildiriş göstərmək lazımdırsa, NotificationManager-dən (sistem bildirişləri) istifadə edin — bu təhlükəsizdir və istifadəçi üçün gözləniləndir. Təxirə salınmış hərəkətlər üçün AlarmManager və ya WorkManager istifadə edin.

Niyə onPause zəmanətli saxlama yeridir, onStop isə yox?

onPause Activity aktiv olmağı dayandırmadan əvvəl zəmanətlə çağırılır. onStop çağırılmaya bilər, əgər sistem yaddaşı boşaltmaq üçün prosesi öldürərsə — bu halda onDestroy da çağırılmır. onPause onResume-dan sonra həmişə çağırılan yeganə metodur, fokus itkisinin səbəbindən asılı olmayaraq. Buna görə bütün kritik məlumatlar məhz onPause-da saxlanılır.

onPause-u vahid testlərdə necə test etmək olar?

onPause-u test etmək üçün AndroidX Test-dən Robolectric və ya FragmentScenario istifadə olunur. FragmentScenario.create() → moveToState(State.STARTED) → moveToState(State.RESUMED) → moveToState(State.STARTED) ardıcıl olaraq onPause-u çağırır. Sonra məlumatların SharedPreferences-də saxlanıldığı və ya kameranın mock-obyekt vasitəsilə boşaldıldığı yoxlanılır. Robolectric 4.12+ fiziki cihaz olmadan onPause/onResume emulasiyasını dəstəkləyir.

Xülasə

  • onPause — Activity daxiletmə fokusunu itirir, lakin qismən görünən qalır; məlumatların saxlanması üçün son zəmanətli nöqtə
  • Saxlama — SharedPreferences.apply() və ya korutinlərlə Room; commit() və sinxron əməliyyatlar qadağandır
  • Resursların boşaldılması — kamera, audio fokus, video pleyer onPause-da digər proqrama ötürmək üçün boşaldılır
  • 100 ms limiti — onPause növbəti Activity-nin render edilməsini bloklayır; limitin aşılması ANR-yə səbəb olur
  • onPause vs onStop — onPause fokus itkisində (görünmə qorunur), onStop tam gizlənmədə
  • Fragment.onPause — Activity.onPause-dan sonra iyerarxik çağırış; xəritələr və ViewPager üçün spesifika
  • Tipik səhvlər — sinxron yazma, dinləyicilərin qeydiyyatı, try/catch-in nəzərə alınmaması, həddindən artıq saxlama
  • super.onPause() — mümkün qədər tez çağırın; buraxılması crash-a səbəb olmur, lakin vəziyyət maşınını pozur

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun