Bu codelab, Android Kotlin Temelleri kursuna dahildir. Codelab'ler üzerinden sırayla çalışıyorsanız bu kurstan en iyi şekilde yararlanabilirsiniz. Tüm kurs codelab'leri Android Kotlin Fundamentals codelabs açılış sayfasında listelenmektedir.
Giriş
Son codelab'de, Activity
ve Fragment
yaşam döngüleri hakkında bilgi edindiniz. Ayrıca yaşam döngüsü durumu etkinliklerde ve parçalarda değiştiğinde çağrılan yöntemleri araştırdınız. Bu codelab'de, etkinlik yaşam döngüsünü daha ayrıntılı bir şekilde keşfedeceksiniz. Android Jetpack'in yaşam döngüsü kitaplığı hakkında da bilgi edindiniz. Bu kitaplık, yaşam döngüsü etkinliklerini daha düzenli ve bakımı kolay bir kodla yönetmenize yardımcı olabilir.
Bilmeniz gerekenler
- Etkinliğin ne olduğu ve uygulamanızda nasıl etkinlik oluşturacağınız.
Activity
veFragment
yaşam döngülerinin temelleri ve bir etkinlik eyaletler arasında hareket ettiğinde çağrılan geri çağırmalar.- Etkinlik veya parça yaşam döngüsünde farklı zamanlarda işlemler gerçekleştirmek için
onCreate()
veonStop()
yaşam döngüsü geri çağırma yöntemleri geçersiz kılınır.
Neler öğreneceksiniz?
- Yaşam döngüsü geri çağırmalarında uygulamanızın bazı bölümlerini ayarlama, başlatma ve durdurma.
- Bir yaşam döngüsü gözlemleyicisi oluşturmak ve etkinlik ile parça yaşam döngüsünün yönetilmesini kolaylaştırmak için Android yaşam döngüsü kitaplığı nasıl kullanılır?
- Android işlemi kapatmalar, uygulamanızdaki verileri nasıl etkiler? Android uygulamanızı kapattığında bu verileri nasıl kaydedip geri yükleyebilirsiniz?
- Cihaz rotasyonu ve diğer yapılandırma değişikliklerinin yaşam döngüsü durumlarında nasıl değişiklik oluşturduğu ve uygulamanızın durumunu nasıl etkilediği.
Ne yaparsınız?
- DessertClicker uygulamasını, bir zamanlayıcı işlevi içerecek şekilde değiştirin ve bu zamanlayıcıyı etkinlik yaşam döngüsü içinde çeşitli zamanlarda başlatıp durdurun.
- Uygulamayı, Android yaşam döngüsü kitaplığını kullanacak şekilde değiştirin ve
DessertTimer
sınıfını yaşam döngüsü gözlemleyicisine dönüştürün. - Uygulamanızın süreç kapatma sürecini ve bu dönemde gerçekleşen yaşam döngüsü geri çağırmalarını simüle etmek için Android Debug Bridge'i (
adb
) ayarlayıp kullanın. - Uygulama beklenmedik bir şekilde kapanırsa kaybolabilecek uygulama verilerini saklamak için
onSaveInstanceState()
yöntemini uygulayın. Uygulama tekrar başladığında bu verileri geri yüklemek için kod ekleyin.
Bu codelab'de, önceki codelab'den DessertClicker uygulamasını genişletiyorsunuz. Bir arka plan zamanlayıcı ekler, ardından uygulamayı Android yaşam döngüsü kitaplığını kullanacak şekilde dönüştürürsiniz.
Önceki codelab'de, çeşitli yaşam döngüsü geri çağırmalarını geçersiz kılarak ve sistem bu geri çağırmaları çağırdığında günlüğe kaydederken etkinliği ve parça yaşam döngülerini nasıl gözlemleyeceğinizi öğrendiniz. Bu görevde, DessertClicker uygulamasında yaşam döngüsü görevlerinin yönetilmesiyle ilgili daha karmaşık bir örnek açıklanmaktadır. Saniyede kaç saniye çalıştığını belirten bir günlük ifadesi yazdıran bir zamanlayıcı kullanırsınız.
1. Adım: Tatlı Zamanlayıcı'yı kurun
- Son codelab'den DessertClicker uygulamasını açın. (Uygulamaya sahip değilseniz DessertClickerLogs'u buradan indirebilirsiniz.)
- Proje görünümünde j&ava > com.example.android.dessertclicker öğesini genişletin ve
DessertTimer.kt
öğesini açın. Şu anda kodun tamamının yorumlandığına dikkat edin. Bu nedenle kod, uygulamanın bir parçası olarak çalışmaz. - Düzenleyici penceresinde tüm kodu seçin. Kod > Satır Yorumu ile Yorum Yap'ı seçin veya
Control+/
(Mac'teCommand+/
) tuşuna basın. Bu komut, dosyadaki tüm kodun açıklamasını kaldırır. (Android Studio, siz uygulamayı yeniden oluşturana kadar çözümlenmemiş referans hataları gösterebilir.) DessertTimer
sınıfının, zamanlayıcıyı başlatan ve durduranstartTimer()
vestopTimer()
öğelerini içerdiğine dikkat edin.startTimer()
çalışırken zamanlayıcı, saniyede çalışan toplam saniye sayısını içeren bir günlük mesajı yazdırır.stopTimer()
yöntemi, zamanlayıcıyı ve günlük ifadelerini durdurur.
MainActivity.kt
'yi açın. Sınıfın üst kısmında,dessertsSold
değişkeninin hemen altına, zamanlayıcı için bir değişken ekleyin:
private lateinit var dessertTimer : DessertTimer;
onCreate()
: Aşağı kaydırın vesetOnClickListener()
çağrısından hemen sonra yeni birDessertTimer
nesnesi oluşturun:
dessertTimer = DessertTimer()
Tatlı zamanlayıcı nesnesine sahip olduğunuza göre, yalnızca ekranda etkinlik varken çalışması için zamanlayıcıyı nereden başlatmanız ve durdurmanız gerektiğini düşünün. Sonraki adımlarda birkaç seçeneği inceleyebilirsiniz.
2. Adım: Zamanlayıcıyı başlatın ve durdurun
onStart()
yöntemi, etkinlik görünür hale gelmeden hemen önce çağrılır. onStop()
yöntemi, etkinliğin görünür hale gelmesinden sonra çağrılır. Bu geri çağırmalar, zamanlayıcının ne zaman başlatılıp durdurulacağı için iyi adaylar gibi görünür.
MainActivity
sınıfındaki zamanlayıcıyıonStart()
geri çağırmasında başlatın:
override fun onStart() {
super.onStart()
dessertTimer.startTimer()
Timber.i("onStart called")
}
onStop()
için zamanlayıcıyı durdur:
override fun onStop() {
super.onStop()
dessertTimer.stopTimer()
Timber.i("onStop Called")
}
- Uygulamayı oluşturun ve çalıştırın. Android Studio'da Logcat bölmesini tıklayın. Logcat arama kutusuna
dessertclicker
(MainActivity
veDessertTimer
sınıflarına göre filtrelenecek şekilde) girin. Uygulama başladıktan sonra zamanlayıcının da hemen çalışmaya başladığına dikkat edin. - Geri düğmesini tıklayın ve zamanlayıcının tekrar durduğuna dikkat edin. Hem etkinlik hem de kontrol ettiği zamanlayıcı yok edildiği için zamanlayıcı durur.
- Uygulamaya dönmek için "Recents" (Son Kullanılanlar) ekranını kullanın. Logcat'te zamanlayıcının 0'dan yeniden başlatıldığına dikkat edin.
- Paylaş düğmesini tıklayın. Catcat'te, zamanlayıcının hâlâ çalışmaya devam ettiğini belirten bildirim.
- Ana Sayfa düğmesini tıklayın. Logcat'te, zamanlayıcının çalışmayı durdurduğuna dair bildirim.
- Uygulamaya dönmek için "Recents" (Son Kullanılanlar) ekranını kullanın. Logcat'te zamanlayıcının kaldığı yerden tekrar başladığına dikkat edin.
MainActivity
yönteminde,onStop()
yöntemindestopTimer()
çağrısına yorum yapın.stopTimer()
etiketini kullandığınızda,onStart()
ürününde bir işlemi başlattığınız gösterilir ancakonStop()
içinde işlemi yeniden durdurmayı unutursanız.- Uygulamayı oluşturup çalıştırın ve zamanlayıcı başladıktan sonra Ana sayfa düğmesini tıklayın. Uygulama arka planda olsa bile zamanlayıcı çalışıyor ve sistem kaynaklarını sürekli olarak kullanır. Zamanlayıcının çalışmaya devam etmesi, uygulamanız için bellek sızıntısı anlamına gelir. Büyük olasılıkla istediğiniz davranış aynı değildir.
Genel olarak, geri çağırma içinde bir şey ayarladığınızda veya başlattığınızda bir çağrıyı geri çağırarak bunu durdurmanız gerekir. Bu şekilde, artık gerekli olmayan öğelerin çalışmasını engelleyebilirsiniz.
onStop()
için zamanlayıcıyı durdurduğunuz hattın yorumunu kaldırın.onStart()
ileonCreate()
arasındastartTimer()
çağrısını kesip yapıştırın. Bu değişiklik, bir kaynağı başlatmak içinonCreate()
, başlatmak içinonStart()
kullanmak yerineonCreate()
ürününde hem kaynağı başlatıp başlattığınız durumu gösterir.- Uygulamayı derleyip çalıştırın. Zamanlayıcının beklediğiniz gibi çalışmaya başladığına dikkat edin.
- Uygulamayı durdurmak için Ana Sayfa'yı tıklayın. Beklediğiniz gibi zamanlayıcı çalışmayı durdurur.
- Uygulamaya dönmek için son kullanılanlar ekranını kullanın. Bu durumda zamanlayıcının yeniden başlamadığını unutmayın. Bunun nedeni,
onCreate()
yalnızca uygulama başladığında çağrılmasıdır. Bir uygulama ön plana döndüğünde çağrılmaz.
Dikkat edilmesi gereken önemli noktalar:
- Bir yaşam döngüsü geri çağırmasında kaynak oluştururken kaynağı da yıkın.
- İlgili yöntemleri kullanarak kurulum ve yıkma işlemleri yapın.
onStart()
'te bir özelliği ayarlarsanızonStop()
'da tekrar durdurun veya yıkın.
DessertClicker uygulamasında, zamanlayıcıyı onStart()
içinde başlattıysanız onStop()
içinde zamanlayıcıyı durdurmanız çok kolaydır. Yalnızca bir zamanlayıcı var. Zamanlayıcıyı durdurmak kolay değil.
Daha karmaşık bir Android uygulamasında, onStart()
veya onCreate()
içerisinde birçok şey ayarlayabilir, ardından tümünü onStop()
veya onDestroy()
'da yıkabilirsiniz. Örneğin, hem kurulum hem de parçalama, başlatma ve durdurma işlemlerini yapmanız gereken animasyonlar, müzik, sensörler veya zamanlayıcılar kullanabilirsiniz. Bunu unutmanız hata ve baş ağrısına neden olur.
Android Jetpack'in bir parçası olan yaşam döngüsü kitaplığı bu görevi basitleştirir. Kitaplık, özellikle bazıları farklı yaşam döngüsü durumlarında bulunan hareketli kısımları takip etmeniz gerektiğinde kullanışlıdır. Kitaplık, yaşam döngülerinin işleyiş şeklini tersine çevirir. Etkinlik veya parça genellikle bir bileşene (DessertTimer
gibi) bir yaşam döngüsü geri çağırması gerçekleştiğinde ne yapılacağını bildirir. Ancak yaşam döngüsü kitaplığını kullandığınızda bileşenin kendisi yaşam döngüsü değişikliklerini izler ve bu değişiklikler gerçekleştiğinde gerekenleri yapar.
Yaşam döngüsü kitaplığının üç ana bölümü vardır:
- Bir yaşam döngüsü olan (ve dolayısıyla yaşam döngüsü) bileşenler olan yaşam döngüsü sahipleri.
Activity
veFragment
yaşam döngüsü sahipleri. Yaşam döngüsü sahipleriLifecycleOwner
arayüzünü uygular. - Bir yaşam döngüsü sahibinin gerçek durumunu tutan ve yaşam döngüsündeki değişiklikler olduğunda etkinlikleri tetikleyen
Lifecycle
sınıfı. - Yaşam döngüsü durumunu gözlemleyen ve yaşam döngüsü değiştiğinde görevleri gerçekleştiren yaşam döngüsü gözetimleri. Yaşam döngüsü gözlemleyicileri
LifecycleObserver
arayüzünü uygular.
Bu görevde DessertClicker uygulamasını dönüştürerek Android yaşam döngüsü kitaplığını kullanacak ve kitaplığın Android etkinliği ve parça yaşam döngülerinin yönetimini nasıl kolaylaştırdığını öğreneceksiniz.
1. Adım: DessertZamanlayıcı'yı bir Yaşam Döngüsü Sunucusuna dönüştürün
Yaşam döngüsü gözlemi, yaşam döngüsü kitaplığının önemli bir parçasıdır. Gözlem, sınıfların (ör. DessertTimer
) etkinlik veya parça yaşam döngüsü hakkında bilgi sahibi olmasını ve yaşam döngüsü durumlarında yapılan değişikliklere yanıt olarak kendi durumunu başlatıp durdurmasını sağlar. Bir yaşam döngüsü gözlemcisiyle, nesneleri etkinlik ve parça yöntemlerinden başlatma ve durdurma sorumluluğunu kaldırabilirsiniz.
DesertTimer.kt
sınıfını açın.DessertTimer
sınıfının sınıf imzasını aşağıdaki gibi değiştirin:
class DessertTimer(lifecycle: Lifecycle) : LifecycleObserver {
Bu yeni sınıf tanımının iki yönü vardır:
- Oluşturucu, zamanlayıcının gözlemlediği yaşam döngüsü olan bir
Lifecycle
nesnesi alır. - Sınıf tanımında
LifecycleObserver
arayüzü uygulanıyor.
runnable
değişkeninin altında, sınıf tanımına birinit
bloğu ekleyin.init
blokunda, sahipten (etkinlik) aktarılan yaşam döngüsü nesnesini bu sınıfa (gözlem) bağlamak içinaddObserver()
yöntemini kullanın.
init {
lifecycle.addObserver(this)
}
@OnLifecycleEvent annotation
ilestartTimer()
için ek açıklama ekleyin veON_START
yaşam döngüsü etkinliğini kullanın. Yaşam döngüsü gözlemleyicinizin gözlemleyebildiği tüm yaşam döngüsü etkinlikleriLifecycle.Event
sınıfındadır.
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun startTimer() {
ON_STOP
etkinliğini kullanarakstopTimer()
için aynı işlemi yapın:
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun stopTimer()
2. Adım: MainActivity'yi değiştirin
FragmentActivity
üst sınıfı LifecycleOwner
uyguladığı için MainActivity
sınıfınız zaten devralma yoluyla bir yaşam döngüsü sahibi. Bu nedenle, etkinliğinizin yaşam döngüsüne duyarlı olması için herhangi bir işlem yapmanız gerekmez. Tek yapmanız gereken, etkinliğin yaşam döngüsü nesnesini DessertTimer
oluşturucuya iletmektir.
MainActivity
'yi açın.onCreate()
yöntemindeDessertTimer
başlatma işleminithis.lifecycle
içerecek şekilde değiştirin:
dessertTimer = DessertTimer(this.lifecycle)
Etkinliğin lifecycle
özelliği, bu etkinliğin sahip olduğu Lifecycle
nesnesini içeriyor.
onCreate()
içindestartTimer()
çağrısını veonStop()
içindestopTimer()
çağrısını kaldırın.DessertTimer
Artık yaşam döngüsünü gözlemlediğinden ve yaşam döngüsü durumu değiştiğinde otomatik olarak bilgilendirildiği için artıkDessertTimer
etkinliğe ne yapmanız gerektiğini söylemeniz gerekmez. Bu geri çağırmalarda tek yapmanız gereken bir mesaj kaydetmek.- Uygulamayı derleyip çalıştırın ve Logcat'i açın. Zamanlayıcının beklendiği gibi çalışmaya başladığına dikkat edin.
- Uygulamayı arka plana almak için ana sayfa düğmesini tıklayın. Zamanlayıcının beklendiği gibi çalışmayı durdurduğuna dikkat edin.
Android, arka plandayken uygulamayı kapatırsa uygulamanıza ve verilerine ne olur? Bu zor uç durumu anlamak önemlidir.
Uygulamanız arka plana geçtiğinde yok olmaz, yalnızca durur ve kullanıcının uygulamaya geri dönmesini bekler. Ancak Android OS'in en önemli sorunlarından biri, ön plandaki etkinliğin sorunsuz bir şekilde çalışmasını sağlamak. Örneğin, kullanıcınız otobüsü yakalamasına yardımcı olacak bir GPS uygulaması kullanıyorsa GPS uygulamasını hızlı bir şekilde oluşturup yol tarifini göstermeye devam etmek önemlidir. Kullanıcının birkaç gün bakmamış olabileceği DessertClicker uygulamasını arka planda sorunsuz bir şekilde çalıştırmak daha az önemlidir.
Android, ön plan uygulamasının sorunsuz çalışabilmesi için arka plan uygulamalarını düzenler. Örneğin, Android'de arka planda çalışan uygulamaların yapabileceği işlem miktarı sınırlanır.
Bazen Android, uygulamayla ilişkili tüm etkinlikleri de içeren bir uygulama sürecini tamamen kapatır. Android, sistem stres altındayken ve görsel olarak gecikme riski altında olduğu için bu tür kapatma yapar. Dolayısıyla bu noktada ek geri çağırma veya kod çalıştırılmaz. Uygulamanızın işlemi arka planda sessizce kapatılır. Ancak kullanıcı uygulamayı kapatmış gibi görünmüyor. Kullanıcı, Android OS'in kapattığı bir uygulamaya geri döndüğünde Android, uygulamayı yeniden başlatır.
Bu görevde Android işleminin kapanmasını simüle eder ve tekrar başladığında uygulamanıza ne olduğunu incelersiniz.
1. Adım: Sürecin kapanmasını simüle etmek için adb'yi kullanın
Android Debug Bridge (adb
), bilgisayarınıza bağlı emülatörlere ve cihazlara talimatlar göndermenize olanak tanıyan bir komut satırı aracıdır. Bu adımda, uygulamanızın işlemini kapatmak ve Android uygulamanızı kapattığında ne olduğunu görmek için adb
özelliğini kullanırsınız.
- Uygulamanızı derleyip çalıştırın. Küçük kek simgesini birkaç kez tıklayın.
- Uygulamanızı arka plana almak için Ana sayfa düğmesine basın. Uygulamanız artık duruyor ve Android'in uygulamanın kullandığı kaynaklara ihtiyacı varsa uygulama kapatılabilir.
- Android Studio'da, komut satırı terminalini açmak için Terminal sekmesini tıklayın.
adb
yazıp Enter tuşuna basın.Android Debug Bridge version X.XX.X
ile başlayıptags to be used by logcat (see logcat —h
elp ile biten çok fazla çıktı görürseniz her şey normaldir. Bunun yerine,adb: command not found
komutunu görüyorsanız yürütme yolunuzdaadb
komutunun kullanılabildiğinden emin olun. Talimatlar için Yardımcı öğeler bölümünde "Yürütme yolunuza adb ekleyin" bölümüne bakın.- Bu yorumu kopyalayıp komut satırına yapıştırın ve Return tuşuna basın:
adb shell am kill com.example.android.dessertclicker
Bu komut, tüm bağlı cihazlara veya emülatörlere, uygulamanın arka planda olması şartıyla dessertclicker
paket adıyla işlemi durdurmalarını bildirir. Uygulamanız arka planda olduğundan cihazda veya emülatör ekranında işleminizin durdurulduğunu belirten hiçbir şey gösterilmez. Android Studio'da, "Uygulama sonlandırıldı" şeklinde bir mesaj görmek için Çalıştır sekmesini tıklayın." onDestroy()
geri çağırma işleminin hiç çalıştırılmadığını görmek için Logcat sekmesini tıklayın. Etkinliğiniz sona erdi.
- Uygulamaya geri dönmek için sonlar ekranını kullanın. Uygulamanız, arka plana yerleştirilmiş veya tamamen durdurulmuş olsa bile son kullanılanlar bölümünde görünür. Uygulamaya dönmek için son kullanılanlar ekranını kullandığınızda, etkinlik tekrar başlar. Etkinlik,
onCreate()
dahil olmak üzere başlangıç yaşam döngüsü geri çağırmalarının tamamından geçer. - Uygulama yeniden başlatıldığında, "skorunuz" (satılmış tatlı sayısı ve toplam dolar) varsayılan değerlere (0) sıfırlanır. Android, uygulamanızı kapatırsa neden durumunuzu kaydetmedi?
OS, uygulamanızı sizin için yeniden başlattığında uygulamanızı daha önceki durumuna sıfırlamak için her türlü çabayı gösterir. Android, bazı görüntülemelerinizin durumunu alır ve etkinlikten ayrıldığınızda pakete kaydeder. Otomatik olarak kaydedilen verilere örnek olarak, EditorText'teki metin (düzende bir kimlik ayarlanmış olduğu sürece) ve etkinliğinizin arka yığınları verilebilir.
Ancak Android OS bazen tüm verilerinizi bilmez. Örneğin, DessertClicker uygulamasındarevenue
gibi bir özelleştirilebilen değişkeniniz varsa Android OS bu veriyi veya etkinliğinizdeki önemini bilmez. Bu verileri gruba kendiniz eklemeniz gerekir.
2. Adım: Paket verilerini kaydetmek için onSaveInstanceState() kullanın
onSaveInstanceState()
yöntemi, Android OS'nin uygulamanızı yok etmesi durumunda ihtiyacınız olabilecek verileri kaydetmek için kullandığınız geri çağırma yöntemidir. Yaşam döngüsü geri çağırma şemasında onSaveInstanceState()
, etkinlik durdurulduktan sonra çağrılır. Uygulamanız arka plana her gittiğinde çağrılır.
onSaveInstanceState()
çağrısını bir güvenlik önlemi olarak düşünün. Bu işlem sayesinde, etkinliğiniz ön plandan çıktıkça pakete az miktarda bilgi kaydedebilirsiniz. Sistem, uygulama kapatılıncaya kadar beklerse işletim sistemi kaynak baskısı altında olabileceğinden bu verileri şimdi kaydeder. Verilerin her defasında kaydedilmesi, gruptaki güncelleme verilerinin gerektiğinde geri yüklenmesini sağlar.
MainActivity
içindeonSaveInstanceState()
geri çağırmasını geçersiz kılın ve birTimber
günlük ifadesi ekleyin.
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
Timber.i("onSaveInstanceState Called")
}
- Uygulamayı oluşturup çalıştırın ve arka plana yerleştirmek için Ana Sayfa düğmesini tıklayın.
onSaveInstanceState()
geri çağırmasınınonPause()
veonStop()
etiketinden hemen sonra gerçekleştiğini unutmayın: - Dosyanın üst kısmında, sınıf tanımının hemen önüne aşağıdaki sabit değerleri ekleyin:
const val KEY_REVENUE = "revenue_key"
const val KEY_DESSERT_SOLD = "dessert_sold_key"
const val KEY_TIMER_SECONDS = "timer_seconds_key"
Örnek durum paketinden hem veri kaydetmek hem de verileri almak için bu anahtarları kullanırsınız.
onSaveInstanceState()
bölümüne gidin veBundle
türündekioutState
parametresine dikkat edin.
Bir paket, anahtar-değer çiftlerinden oluşan bir koleksiyondur. Burada anahtarlar her zaman dizedir.int
veboolean
değerleri gibi temel değerleri gruba yerleştirebilirsiniz.
Sistem bu paketi RAM'de sakladığından paketteki verileri küçük tutmak için en iyi uygulamadır. Bu paketin boyutu da sınırlıdır, ancak cihazdan cihaza farklılık gösterebilir. Genellikle 100 binden daha az depolama alanı kullanmanız gerekir. Aksi takdirde uygulamanızTransactionTooLargeException
hatasıyla kilitlenebilir.onSaveInstanceState()
olarak,putInt()
değerini kullanarakrevenue
değerini (tam sayı) pakete yerleştirin:
outState.putInt(KEY_REVENUE, revenue)
putInt()
yöntemi (ve Bundle
sınıfındaki putFloat()
ve putString()
gibi benzer yöntemler) iki bağımsız değişken alır: Anahtar için bir dize (KEY_REVENUE
sabit değeri) ve tasarruf edilecek gerçek değer.
- Aynı işlemi satılan tatlı sayısı ve zamanlayıcının durumuyla birlikte tekrarlayın:
outState.putInt(KEY_DESSERT_SOLD, dessertsSold)
outState.putInt(KEY_TIMER_SECONDS, dessertTimer.secondsCount)
3. Adım: Paket verilerini geri yüklemek için onCreate() öğesini kullanın
onCreate()
bölümüne ilerleyin ve yöntem imzasını inceleyin:
override fun onCreate(savedInstanceState: Bundle) {
onCreate()
her çağrıldığında bir Bundle
aldığına dikkat edin. İşleminizin kapanması nedeniyle etkinliğiniz yeniden başlatıldığında, kaydettiğiniz paket onCreate()
hesabına aktarılacak. Etkinliğiniz yeni başlamışsa onCreate()
grubundaki bu grup null
. Yani paket null
değilse önceden bilinen bir noktadan, etkinliği yeniden oluşturduğunuzu bilirsiniz.
onCreate()
adlı kodaDessertTimer
kurulumundan sonra şu kodu ekleyin:
if (savedInstanceState != null) {
revenue = savedInstanceState.getInt(KEY_REVENUE, 0)
}
null
testi, pakette veri olup olmadığını veya paketin null
olup olmadığını belirler. Bu da uygulamanın yeni başlatılıp başlatılmadığını veya kapatıldıktan sonra yeniden oluşturulup oluşturulmadığını gösterir. Bu test, paketten veri geri yüklemek için yaygın olarak kullanılan bir kalıptır.
Burada kullandığınız anahtarın (KEY_REVENUE
) putInt()
için kullandığınız anahtarla aynı olduğuna dikkat edin. Her seferinde aynı anahtarı kullandığınızdan emin olmak için bu anahtarları sabit değer olarak tanımlamanız önerilir. getInt()
verilerini paketten çıkarmak için olduğu gibi, verileri pakete yerleştirmek için olduğu gibi putInt()
kullanırsınız. getInt()
yöntemi iki bağımsız değişken alır:
- Anahtar işlevi gören bir dize. Örneğin, gelir değeri için
"key_revenue"
. - Paketteki anahtar için herhangi bir değer yoksa varsayılan değer kullanılabilir.
Paketten aldığınız tam sayı revenue
değişkenine atanır ve kullanıcı arayüzünde bu değer kullanılır.
- Satılan tatlı sayısını ve zamanlayıcının değerini geri yüklemek için
getInt()
yöntemleri ekleyin:
if (savedInstanceState != null) {
revenue = savedInstanceState.getInt(KEY_REVENUE, 0)dessertsSold = savedInstanceState.getInt(KEY_DESSERT_SOLD, 0)
dessertTimer.secondsCount =
savedInstanceState.getInt(KEY_TIMER_SECONDS, 0)
}
- Uygulamayı derleyip çalıştırın. Donut'a geçene kadar kek düğmesine en az beş kez basın. Uygulamayı arka plana almak için Ana Sayfa'yı tıklayın.
- Android Studio Terminal sekmesinde
adb
işlemini çalıştırarak uygulamanın işlemini kapatın.
adb shell am kill com.example.android.dessertclicker
- Uygulamaya geri dönmek için "Recents" (Son Kullanılanlar) ekranını kullanın. Uygulamanın bu sefer doğru gelirle döndüğünü ve pakette satılan tatlı değerler bulunduğunu unutmayın. Ancak, pastanın tekrar pastaya döndüğünü unutmayın. Uygulamanın kapanmadan tam olarak kaldığı gibi geri gelmesini sağlamak için yapmanız gereken bir şey daha var.
MainActivity
içinde,showCurrentDessert()
yöntemini inceleyin. Bu yöntemin, satılan mevcut tatlı sayısına veallDesserts
değişkenindeki tatlı listesine göre etkinlikte hangi tatlı resminin gösterileceğini belirlediğine dikkat edin.
for (dessert in allDesserts) {
if (dessertsSold >= dessert.startProductionAmount) {
newDessert = dessert
}
else break
}
Bu yöntem, doğru resmi seçmek için satılan tatlı sayısına dayanır. Bu nedenle, onSaveInstanceState()
'deki paketteki resme referans vermek için herhangi bir işlem yapmanız gerekmez. Bu pakette, satılan tatlı sayısını zaten depoluyorsunuz.
onCreate()
içinde, durumu paketten geri yükleyen blokta şunu ara:showCurrentDessert()
:
if (savedInstanceState != null) {
revenue = savedInstanceState.getInt(KEY_REVENUE, 0)
dessertsSold = savedInstanceState.getInt(KEY_DESSERT_SOLD, 0)
dessertTimer.secondsCount =
savedInstanceState.getInt(KEY_TIMER_SECONDS, 0)
showCurrentDessert()
}
- Uygulamayı derleyip arka planda çalıştırın. İşlemi kapatmak için
adb
kullanın. Uygulamaya geri dönmek için sonlar ekranını kullanın. Hem söylenen tatlıların değerlerinin, toplam gelirin ve tatlı resminin doğru şekilde geri yüklendiğini unutmayın.
Etkinlik ve parça yaşam döngüsünün yönetilmesinde son derece özel bir durum vardır: Yapılandırma değişiklikleri, etkinliklerinizin ve parçalarınızın yaşam döngüsünü nasıl etkiler?
Bir yapılandırma değişikliği, cihaz durumu büyük ölçüde değiştiğinde sistem tarafından değişikliğin en kolay yolu etkinliği tamamen kapatıp yeniden oluşturmaktır. Örneğin, kullanıcı cihazın dilini değiştirirse tüm düzenin farklı metin yönlerine uygun olacak şekilde değişmesi gerekebilir. Kullanıcı cihazı bir yuvaya bağlarsa veya fiziksel bir klavye eklerse uygulama düzeninin farklı bir ekran boyutundan veya düzeninden yararlanması gerekebilir. Ayrıca, cihazın yönü değişirse (cihaz dikeyden yataya veya tam tersi yönde döndürülürse) düzenin yeni yöne sığacak şekilde değişmesi gerekebilir.
1. Adım: Cihaz rotasyonunu ve yaşam döngüsü geri çağırmalarını keşfedin
- Uygulamanızı derleyip çalıştırın ve Logcat'i açın.
- Cihazı veya emülatörü yatay moda döndürün. Rotasyon düğmelerini veya
Control
ve ok tuşlarını (Mac'teCommand
ve ok tuşları) kullanarak emülatörü sola veya sağa döndürebilirsiniz. - Logcat'teki çıkışı inceleyin. Çıkışı
MainActivity
üzerinde filtreleyin.
Cihaz veya emülatör ekranı çevirdiğinde, sistemin tüm yaşam döngüsü geri çağırmalarını çağırarak etkinliği kapatmasını sağlar. Ardından, etkinlik yeniden oluşturulurken sistem, etkinliği başlatmak için tüm yaşam döngüsü geri çağırmalarını çağırır. MainActivity
içinde,onSaveInstanceState()
yönteminin tamamına yorum yapın.- Uygulamanızı derleyip tekrar çalıştırın. Mini kek simgesini birkaç kez tıklayın ve cihazı veya emülatörü döndürün. Bu kez cihaz döndürüldüğünde ve etkinlik kapatılıp yeniden oluşturulduğunda etkinlik, varsayılan değerlerle başlar.
Bir yapılandırma değişikliği olduğunda, Android, uygulamanın durumunu kaydetmek ve geri yüklemek için önceki görevde öğrendiğiniz örnek durum paketini kullanır. Bir işlem kapatıldığında olduğu gibi, uygulamanızın verilerini pakete yerleştirmek içinonSaveInstanceState()
öğesini kullanın. Ardından, cihaz döndürüldüyse etkinlik durumu verilerini kaybetmemek içinonCreate()
ürününde verileri geri yükleyin. MainActivity
içinde,onSaveInstanceState()
yönteminin açıklamasını kaldırın, uygulamayı çalıştırın, kupayı tıklayın ve uygulamayı veya cihazı döndürün. Bu süre zarfında tatlı veriler etkinlik rotasyonu boyunca saklanır.
Android Studio projesi: DessertClickerFinal
Yaşam döngüsü ipuçları
- Bir yaşam döngüsü geri çağırmasında bir özellik ayarlar veya başlatırsanız ilgili geri çağırmada bu öğeyi durdurun veya kaldırın. İşlemi durdurduğunuzda, artık ihtiyaç duyulmayan durumlarda çalışmaya devam etmesini önlersiniz. Örneğin,
onStart()
ürününde bir zamanlayıcı ayarlarsanızonStop()
içindeki zamanlayıcıyı duraklatmanız veya durdurmanız gerekir. onCreate()
özelliğini, yalnızca uygulamanın bir kez çalıştırılan bölümlerini başlatmak için kullanın. Uygulamanızın hem uygulama başladığında hem de uygulama ön plana her döndüğünde çalıştırılan bölümlerini başlatmak içinonStart()
öğesini kullanın.
Yaşam döngüsü kitaplığı
- Yaşam döngüsü kontrolünü, etkinlik veya parçadan yaşam döngüsüne duyarlı olması gereken gerçek bileşene kaydırmak için Android yaşam döngüsü kitaplığını kullanın.
- Yaşam döngüsü sahipleri,
Activity
veFragment
dahil olmak üzere yaşam döngülerine sahip (ve dolayısıyla) yaşam bileşenleridir. Yaşam döngüsü sahipleriLifecycleOwner
arayüzünü uygular. - Yaşam döngüsü gözlemleri, mevcut yaşam döngüsü durumuna dikkat eder ve yaşam döngüsü değiştiğinde görevleri gerçekleştirir. Yaşam döngüsü gözlemleyicileri
LifecycleObserver
arayüzünü uygular. Lifecycle
nesneleri gerçek yaşam döngüsü durumlarını içerir ve yaşam döngüsü değiştiğinde etkinlikleri tetikler.
Yaşam döngüsüne duyarlı bir sınıf oluşturmak için:
LifecycleObserver
arayüzünü yaşam döngüsüne duyarlı olması gereken sınıflara uygulayın.- Etkinlik veya parçadan yaşam döngüsü nesnesiyle bir yaşam döngüsü gözlemci sınıfını başlatın.
- Yaşam döngüsü gözlemci sınıfında, yaşam döngüsü duyarlı yöntemlere, ilgilendikleri yaşam döngüsü durumu değişikliğiyle ek açıklama ekleyin.
Örneğin,@OnLifecycleEvent(Lifecycle.Event.ON_START)
ek açıklama, yönteminonStart
yaşam döngüsü etkinliğini izlediğini gösterir.
İşlemleri kapatma ve etkinlik durumunu kaydetme
- Android, ön planda çalışan uygulamaların sorunsuz çalışabilmesi için arka planda çalışan uygulamaları düzenler. Bu düzenleme, arka plandaki uygulamaların yapabileceği işleme miktarını sınırlandırmayı ve hatta tüm uygulama sürecinizi kapatmayı içerir.
- Kullanıcı, sistemin arka planda bir uygulamayı kapatıp kapatmadığını belirleyemez. Uygulama, son kullanılanlar ekranında görünmeye devam eder ve kullanıcının kaldığı yerden yeniden başlar.
- Android Debug Bridge (
adb
), bilgisayarınıza bağlı emülatörlere ve cihazlara talimatlar göndermenize olanak tanıyan bir komut satırı aracıdır. Uygulamanızdaki bir işlemin kapanmasını simüle etmek içinadb
kullanabilirsiniz. - Android, uygulama sürecinizi kapattığında
onDestroy()
yaşam döngüsü yöntemi çağrılmaz. Uygulama duruyor.
Etkinlik ve parça durumunu koruma
- Uygulamanız arka plana gittiğinde,
onStop()
çağrıldıktan hemen sonra uygulama verileri bir gruba kaydedilir.EditText
içeriği gibi bazı uygulama verileri sizin için otomatik olarak kaydedilir. - Paket, anahtar ve değerlerin bir koleksiyonu olan
Bundle
öğesinin bir örneğidir. Anahtarlar her zaman dizedir. - Uygulama otomatik olarak kapatılmış olsa bile, saklamak istediğiniz pakete diğer verileri kaydetmek için
onSaveInstanceState()
geri çağırmasını kullanın. Verileri pakete yerleştirmek içinput
ile başlayan paket yöntemlerini kullanın (örneğin,putInt()
). onRestoreInstanceState()
uygulamasından veya daha sık olarakonCreate()
içinden paketin verilerini geri alabilirsiniz.onCreate()
yönteminde paketi içeren birsavedInstanceState
parametresi var.savedInstanceState
değişkeninull
içeriyorsa etkinlik bir durum paketi olmadan başlamıştır ve alınacak durum verisi yoktur.- Paketten anahtarla veri almak için
get
ile başlayanBundle
gibi yöntemleri (ör.getInt()
) kullanın.
Yapılandırma değişiklikleri
- Bir yapılandırma değişikliği, cihaz durumu büyük ölçüde değiştiğinde ve sistemdeki değişikliği çözmenin en kolay yolu, etkinliği kapatıp yeniden oluşturmaktır.
- Bir yapılandırma değişikliğinin en yaygın örneği, kullanıcının cihazı dikey moddan yatay moda veya yatay moddan dikey moda döndürmesidir. Cihaz dili değiştiğinde veya donanım klavyesi takıldığında da bir yapılandırma değişikliği söz konusu olabilir.
- Bir yapılandırma değişikliği olduğunda Android, tüm etkinlik yaşam döngüsünü ve geri çağırma geri çağırmalarını çağırır. Daha sonra Android, etkinliği tüm yaşam döngüsü geri çağırma geri çağırma işlemlerini çalıştırarak en baştan başlatır.
- Android, yapılandırma değişikliği nedeniyle bir uygulamayı kapattığında,
onCreate()
tarafından kullanılabilen durum paketi ile etkinliği yeniden başlatır. - İşlemin kapanmasında olduğu gibi uygulamanızın durumunu
onSaveInstanceState()
içindeki pakete kaydedin.
Udacity kursu:
Android geliştirici dokümanları:
- Etkinlikler (API kılavuzu)
Activity
(API referansı)- Etkinlik Yaşam Döngüsünü Anlama
- Yaşam Döngüsüne Duyarlı Bileşenlerle Yaşam Döngülerini Yönetme
LifecycleOwner
Lifecycle
LifecycleObserver
onSaveInstanceState()
- Yapılandırma değişikliklerini işleme
- Kullanıcı arayüzü durumlarını kaydetme
Diğer:
- Timber (GitHub)
Bu bölümde, bir eğitmen tarafından sunulan kurs kapsamında bu codelab üzerinden çalışan öğrenciler için olası ev ödevi ödevleri listelenmektedir. Öğretmenin şunları yapması gerekir:
- Gerekirse ev ödevini atayın.
- Öğrencilere ev ödevlerinin nasıl gönderileceğini bildirin.
- Ev ödevlerine not verin.
Öğretmenler bu önerileri istedikleri kadar kullanabilir veya uygun görebilir ve uygun olan diğer ev ödevlerini atayabilirler.
Bu codelab'de kendiniz çalışıyorsanız, bilginizi test etmek için bu ödevlerden yararlanabilirsiniz.
Uygulamaları değiştirme
1. Ders'teki DiceRoller uygulamasını açın. (Uygulamayı indirmediyseniz buradan indirebilirsiniz.) Uygulamayı derleyip çalıştırın. Cihazı döndürdüğünüzde zarın mevcut değerinin kaybolacağını unutmayın. Paketteki bu değeri korumak için onSaveInstanceState()
özelliğini uygulayın ve onCreate()
içinde bu değeri geri yükleyin.
Bu soruları yanıtlayın
1. Soru
Uygulamanız, görüntülenmesi için yoğun hesaplama gerektiren bir fizik simülasyonu içeriyor. Daha sonra kullanıcı bir telefon araması alır. Aşağıdaki ifadelerden hangisi doğrudur?
- Telefon görüşmesi sırasında, fizik simülasyonunda nesnelerin konumlarını hesaplamaya devam etmeniz gerekir.
- Telefon araması sırasında, fizik simülasyonunda nesnelerin konumlarının durması gerekir.
2. Soru
Uygulama ekranda değilken simülasyonu duraklatmak için hangi yaşam döngüsü yöntemini geçersiz kılmanız gerekir?
onDestroy()
onStop()
onPause()
onSaveInstanceState()
3. Soru
Android yaşam döngüsü kitaplığı aracılığıyla bir sınıfın yaşam döngüsünü fark edebilmesi için sınıf hangi arayüzü uygulamalıdır?
Lifecycle
LifecycleOwner
Lifecycle.Event
LifecycleObserver
4. Soru
Hangi durumlarda etkinliğinizdeki onCreate()
yöntemi, içinde veri bulunan bir Bundle
alır (yani Bundle
, null
değildir). Birden fazla yanıt geçerli olabilir.
- Cihaz döndürüldükten sonra etkinlik yeniden başlatılır.
- Etkinlik sıfırdan başlatılır.
- Etkinlik arka plandan dönüldükten sonra devam ettirilir.
- Cihaz yeniden başlatılır.
Sonraki dersi başlatın:
Bu kurstaki diğer codelab'lerin bağlantılarına ulaşmak için Android Kotlin Fundamentals codelabs açılış sayfasına göz atın.