Activity sona erdirilmesi ve Verinin(state) kaydedilmesi

Kısaca uygulamanın içinde herhangi bir yerinde finish() metoduyla ya da sistemin bellekte yer açması sebebiyle bir Activity öldürülür. Bu yazıda yaşam döngüsü sona eren bir Activity yeniden nasıl oluşturulur ondan bahsedeceğim.

1.1. Out-of-memory killer

Sınırlı donanım sebebiyle Android sistemi çalışan uygulamaları kapatmak zorunda kalır. Peki sistem uygulamaları kapatmak istediğinde hangi sırayı gözetir yani uygulamaların öncelik sırası nasıldır? Aşağıda önem sırasına göre sıraladığım durumdaki uygulamaları sistem LRU (least recent used) listesine sıralar ve gerektiğinde bellekte yer açmak için bu listeyi kullanır.

  1. Ön plandaki uygulamalar. Kullanıcının bir Activity ile ya da bir Service ile etkileşime girdiği uygulamalar.
  2. Görünür uygulamalar. Kullanıcının gözüken bir Activity ile direk etkileşime girmediği ya da uygulamanın bir Service’inin etkin olmayan fakat görünür bir Activity tarafından kullanıldığı durumdaki uygulamalar.
  3. Service. Uygulamanın ilk iki durumla da uyuşmayan çalışan bir Service’e sahip olması.
  4. Arkaplandaki uygulama. Service veya bir receiver olmadan sadece duraklamış Activity’e sahip durumdaki uygulamalar.
  5. Boş uygulama. Herhangi bir aktif bir şeye sahip olmayan uygulamalar.

LRU listesinin en başındaki ilk olarak öldürülür. Eğer kullanıcı bir uygulamayı yeniden başlattıysa listenin en sonuna konur.

1.2. Uygulama

Bir uygulama başlatıldığında uygulama nesnesi ilk başlatılan ve uygulama sonlandırılırken en son öldürülen şeydir. (FILO)

Override edilebilir ana yaşam döngüsü metodları şunlardır:

  • onCreate() : Uygulamanın ilk komponentleri başlamadan önce çalıştırılan metoddur.
  • onLowMemory() : Uygulama Android sistemi tarafından bellekten kaldırılmak istendiğinde çağrılır.
  • onTrimMemory() : Yine uygulama Android sistemi tarafından bellekten kaldırılmak istendiğinde çağrılır. TRIM_MEMORY_RUNNING_CRITICAL, TRIM_MEMORY_MODERATE gibi mesaj içeren birçok değerle çalışır ve switch-case ile kullanılır.
  • Bu arada onLowMemory() metodu TRIM_MEMORY_COMPLETE’ in dengidir.
  • onTerminate() : Test aşamasında kullanılır.
  • onConfigurationChanged() : Cihazın yönü değiştiğinde veya klavyenin kapandığı gibi durumlarda çağrılır.

2.1. Activity state’leri

ÖncelikGörünürlükState
En azForegroundCreated / Resumed / Paused
OrtaBackgroundPaused
En fazlaBackground / EmptyStopped / Destroyed

Activity yaşam döngüsü metodlarını görmek için bu yazıma bakabilirsiniz.

Bu arada sistem aslında bir uygulamayı direkt  öldürmez. Bunun yerine sadece içindeki Activity’nin yürütüldüğü Process’i öldürür.

2.2. Activity’lerin öldürülmesi

Herhangi bir konfigürasyon değişimi durumunda sistem görünürdeki Activity’i yeniden başlatır.

Ayrıca sistem uygulamanın çalıştığı Process’i sonlandırdığında tüm Activity’ler de mantıken sonlanır ve bu sırada her Activity’nin yaşam döngüsü metodları çalıştırılır.

Diğer yazımda belirttiğim gibi onPause() metoduyla listener’lar ve UI framework’ları sonlandırılır ve onStop() metoduyla da uygulama verisi kaydedilir.

Eğer kullanıcı, sistem tarafından sonlandırılmış olan uygulamaya geri dönerse uygulama tekrar başlatılır. Ayrıca Activity yığını tekrar başlatılır ve onResume() metoduyla listener ve UI framework’ları kaydedilmiş veriyle tekrar başlatılır.

2.3. Activity Instance State

Instance state dediğimiz şey bir Activity’nin arayüz durumudur ve geçicidir yani uygulama tamamen kapandığında kaybolur. Konfigürasyon değişikliği olduğunda Activity restart’ları arasında devredilir. Bir Activity kendi durum verisini kaydetmek ve geri yüklemekle sorumludur.

onSaveInstanceState() metodu ile bu veri Bundle olarak kaydedilir. Bir Bundle ilkel veri tipleri, string, Parcelable ya da Serialisable türündeki objeleri veya her üçünün array halini içerebilir. Bu Bundle verisi Activity restart olduğunda onCreate() ve onRestoraInstanceState() metoduna parametre olarak aktarılır ve bu iki metodla Activity UI durumu tekrar oluşturulur.

onSaveInstanceState() ve onRestoraInstanceState() metodları override edildiğinde super keyword’ü kullanılmak zorundadır çünkü bu keyword’ü kullanılarak View.onSaveInstanceState çağrılır ve Activity state ancak bu şekilde kaydedilir.

NOT:

  • onSaveInstanceState() ile kalıcı olmayan, arayüzün durum verisi kaydedilir.
  • onPause() metoduyla uygulama boyunca kullanılacak olan kalıcı veri kaydedilir.

Kullanıcının etkileşimde olduğu bir Activity, Geri tuşuyla ya da finish() metoduyla sonlandırıldığında Activity sonlandırılarak yığından kaldırılır. Bu durumda Activity state kaydedilmez ve onSaveInstanceState() metodu da çağırılmaz. İkinci olarak, kullanıcı Home tuşuna bastığında Activity yine yığından kaldırılır. Fakat bu sefer durum kaydedilir ve onSaveInstanceState() metodu çağırılır. Kullanıcı uygulamaya geri döndüğünde, Activity sistem tarafından sonlandırıldıysa tekrar Activity yığını oluşturulur ve Bundle objesi bu sefer onRestoreInstanceState() ve onCreate() metodlarına parametre olarak gönderilir.