Uygulamada çeşitli yollarla (kullanıcının geri tuşuna basması, Activity'nin finish() metodunu çagırması gibi) Activity'nin sonlanması ya da İngilizce tabiriyle "destroy" olması, gayet doğal bir işlemdir. Sistemin daha fazla belleğe ihtiyacı olduğunda ya da Activity çok uzun süredir çalıştığı için durdurulabilir. Bu eğitim belgesinde sonlanan bir Activity'nin yeniden nasıl başlatılacağını anlatacağız.
Activity, kullanıcının geri tuşuna basması ya da kendini sonlandırması (finish()) durumlarında tamamıyla kaybolur çünkü sistem Activity'nin artık gerekli olmadığını farzeder. Activity sistem tarafından sonlandırıldıysa Activity'de bulunan verileri saklayıp, kullanıcı geri dönmek istediğinde yeniden Activity oluşturarak bu verileri ona yükler. Activity'nin hangi adımda olduğunu sakladığı için yine o duruma gelerek kullanıcının kaldığı son ekranı gösterir. Sistem tarafından korunan veriler Bundle objesinde anahtar-değer çiftleriyle tutulur.
Normalde sistem Bundle kullanarak uygulamanın Activity layout'unda bulunan tüm view nesnelerini saklar (editext'e girilen değer gibi). Eğer Activity'niz sonlanır ve yeniden başlatılırsa layout dosyasındaki nesnelerin son değerleri korunur. Sizin kodunuzu gerektirmeyen bu özellikle birlikte kullanıcı deneyiminin artırılması ve uygulamanın daha verimli çalışması için daha fazla veri ve durumun kazanılması gerekebilir, bunun için Activity'nin ilerleyişini çeşitli değişkenlerle saklamanız gerekmektedir.
Android sisteminin son durum değerlerini kurtarabilmesi için tüm View'lar android:id niteliğinden sağlanan benzersiz (unique) ID'ye sahip olmak zorundadır.
Activity durumları için daha fazla veri kaydetmek isterseniz,onSaveInstanceState() callback methodunu ezmeniz (override) gerekmektedir. Sistem, kullanıcı Activity'den çıktığında metodun sakladığı verileri Bundle nesnesine yükleyerek, sistem Activity'yi yeniden oluşturmak durumunda kalırsa onRestoreInstanceState() veya onCreate() metodunu çağırdığında aynı Bundle nesnesini kullanır.
Activity State'inin kaydedilmesi
Uygulamanızın Activity'si durmaya başladığında, sistem tarafından onSaveInstanceState() metodu çağrılır, bu yolla uygulamanızın Activity state'ini anahtar-değer çiftleriyle kaydebilirsiniz. Metodun olağan gerçeklemesinde (default implementation) Activity'nin durumunu View hiyerarşisine göre kaydedilir. Örneğin EditText içerisindeki bir değer ya da ListView öğesi içinde ekranın kaydırılma miktarının kaydedilmesi gibi.
Eğer Activity'nin daha fazla durum bilgilerini kaydetmek istiyorsanız, onSaveInstanceState() metoduna yeni kod eklemeleri yaparak Bundle nesnesine anahtar-değer çifti belirtmek durumundasınız. Kod örneğimizle konu daha iyi anlaşılacaktır:
static final String STATE_SCORE = "playerScore";
static final String STATE_LEVEL = "playerLevel";
...
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// kullanıcının o anki durumunu kaydediyoruz
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);
// Her zaman superclass'ı çağırarak methodun temel işlevini de yerine getirmesini sağlıyoruz
super.onSaveInstanceState(savedInstanceState);
}
Dikkat: Her zaman onSaveInstanceState()'in superclass'ını çağırmalısınız ki, metodun varsayılan gerçeklemesi View hiyerarşisinin durumunu da kaydedebilsin.
Activity State'ini yeniden yüklemek
Activity'niz yeniden yaratıldığında, yok edilmeden önceki Bundle nesnesine kaydedilmiş durum bilgilerini yükleyebilirsiniz. onCreate() ve onRestoreInstanceState() metodları çağrıldığında Bundle nesnesinin üzerinden geçerek durum bilgisini yeniden yüklerler.
Sistem tarafından Activity'nizin yeni bir instance'ı (sınıf örneği) oluştururulduğunda ya da sistem önceki Activity'yi yeniden yarattığında onCreate() metodu çalışacaktır. onCreate() metodu çağrıldığında Bundle nesnesinin null (boş) olup olmadığını kontrol etmelisiniz. Eğer null ise sistem yeni bir Activity oluşturur. Eğer Bundle null değilse eski Activity'nin değerlerini yükleyecektir.
Örneğimizle bir Activity'nin Bundle nesnesi boş değilse eski değerleri nasıl yüklediğimizi görelim:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // her zaman öncelikle superclass'ı çağırıyoruz
// önceden yok edilen instance'i yaratıp yaratmadığımızı kontrol edelim
if (savedInstanceState != null) {
// kaydedilen eski activity değerlerini yüklüyoruz.
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
} else {
// yeni bir activity yaratıyoruz
}
...
}
onCreate metoduyla bilgileri yeniden yüklemek yerine onRestoreInstanceState() metoduyla durum bilgilerini getirebilirsiniz. Sistem onStart metodu sonrası otomatik olarak bu metodu çağırdığı için Bundle'ın null olup olmadığını kontrol etmek zorunda kalmazsınız. Örneğimizle bu metodu nasıl kullanıldığını görebilirsiniz:
public void onRestoreInstanceState(Bundle savedInstanceState) {
// view hiyerarşinin korunması için her zaman öncelikle superclass'ı çağırıyoruz.
super.onRestoreInstanceState(savedInstanceState);
// kaydedilen durumların yeniden yüklenmesi
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
Dikkat: onRestoreInstanceState() metodunda view hiyerarşinin korunması için her zaman öncelikle superclass'ı çağırıyoruz.
Bu sayfadaki parçalar Android Open Source Project kapsamında oluşturulmuş ve paylaşılmış içeriğin küçük değişiklikler yapılmış hâlidir ve Creative Commons 2.5 Attribution License'ta belirlenen koşullara göre kullanılmıştır.
Bu eğitim içeriğinin orijinal hâline buradan ulaşabilirsiniz: Recreating an Activity