Bu codelab, Android Kotlin Hakkında Temel Bilgiler kursunun bir parçasıdır. Bu kurstan en iyi şekilde yararlanmak için codelab'leri sırayla tamamlamanızı öneririz. Kursla ilgili tüm codelab'ler Android Kotlin Hakkında Temel Bilgiler codelab'leri açılış sayfasında listelenir.
Giriş
Son codelab'de Activity ve Fragment yaşam döngüleri hakkında bilgi edinmiş ve yaşam döngüsü durumu etkinliklerde ve parçalarda değiştiğinde çağrılan yöntemleri incelemiştiniz. Bu codelab'de etkinlik yaşam döngüsünü daha ayrıntılı bir şekilde inceliyorsunuz. Ayrıca, daha iyi düzenlenmiş ve bakımı daha kolay kodlarla yaşam döngüsü etkinliklerini yönetmenize yardımcı olabilecek Android Jetpack'in yaşam döngüsü kitaplığı hakkında da bilgi edineceksiniz.
Bilmeniz gerekenler
- Etkinlik nedir ve uygulamanızda nasıl etkinlik oluşturabilirsiniz?
ActivityveFragmentyaşam döngülerinin temelleri ve bir etkinlik durumlar 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öntemlerini nasıl geçersiz kılacağınız.
Neler öğreneceksiniz?
- Yaşam döngüsü geri çağırma yöntemlerinde uygulamanızın bölümlerini nasıl ayarlayacağınız, başlatacağınız ve durduracağınız.
- Yaşam döngüsü gözlemcisi oluşturmak ve etkinlik ile parça yaşam döngüsünü daha kolay yönetmek için Android yaşam döngüsü kitaplığının nasıl kullanılacağı.
- Android'in işlem kapatma işlemlerinin uygulamanızdaki verileri nasıl etkilediği ve Android uygulamanızı kapattığında bu verileri otomatik olarak nasıl kaydedip geri yükleyebileceğiniz.
- Cihaz döndürme ve diğer yapılandırma değişikliklerinin yaşam döngüsü durumlarında nasıl değişiklikler oluşturduğu ve uygulamanızın durumunu nasıl etkilediği.
Yapacaklarınız
- DessertClicker uygulamasını zamanlayıcı işlevi içerecek şekilde değiştirin ve bu zamanlayıcıyı etkinlik yaşam döngüsünün çeşitli zamanlarında başlatıp durdurun.
- Uygulamayı Android yaşam döngüsü kitaplığını kullanacak şekilde değiştirin ve
DessertTimersınıfını yaşam döngüsü gözlemcisine dönüştürün. - Uygulamanızın işlem kapatma sürecini ve bu süreçte gerçekleşen yaşam döngüsü geri çağırmalarını simüle etmek için Android Debug Bridge'i (
adb) kurup kullanın. - Uygulama beklenmedik şekilde kapatılı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'deki DessertClicker uygulamasını genişleteceksiniz. Arka plan zamanlayıcı ekleyip uygulamayı Android yaşam döngüsü kitaplığını kullanacak şekilde dönüştürürsünüz.

Ö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ük kaydı oluşturarak etkinlik 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örevlerini yönetmeyle ilgili daha karmaşık bir örneği inceleyeceksiniz. Çalışma süresinin saniye sayısını içeren bir günlük ifadesini her saniyede bir yazdıran bir zamanlayıcı kullanacaksınız.
1. adım: DessertTimer'ı ayarlayın
- Son codelab'deki DessertClicker uygulamasını açın. (Uygulamanız yoksa DessertClickerLogs'u buradan indirebilirsiniz.)
- Proje görünümünde, java > com.example.android.dessertclicker'ı genişletin ve
DessertTimer.kt'ı açın. Şu anda kodun tamamının yorum satırı olarak işaretlendiğini, dolayısıyla uygulamanın bir parçası olarak çalışmadığını unutmayın. - Düzenleyici penceresindeki tüm kodu seçin. Code > Comment with Line Comment'ı (Kod > Satır Yorumuyla Yorum Yap) seçin veya
Control+/tuşuna (Mac'teCommand+/) basın. Bu komut, dosyadaki tüm kodların yorum satırı olmaktan çıkarılmasını sağlar. (Android Studio, uygulamayı yeniden oluşturana kadar çözümlenmemiş referans hataları gösterebilir.) DessertTimersınıfının, zamanlayıcıyı başlatan ve durduranstartTimer()vestopTimer()sınıflarını içerdiğini unutmayın.startTimer()çalışırken zamanlayıcı, her saniyede bir günlük mesajı yazdırır. Bu mesajda, zamanlayıcının çalıştığı toplam süre de yer alır.stopTimer()yöntemi ise zamanlayıcıyı ve günlük ifadelerini durdurur.
MainActivity.ktadlı kişiyi aç. Sınıfın üst kısmında,dessertsSolddeğişkeninin hemen altına zamanlayıcı için bir değişken ekleyin:
private lateinit var dessertTimer : DessertTimer;onCreate()bölümüne gidin vesetOnClickListener()çağrısından hemen sonra yeni birDessertTimernesnesi oluşturun:
dessertTimer = DessertTimer()
Artık bir tatlı zamanlayıcı nesneniz olduğuna göre, zamanlayıcının yalnızca etkinlik ekrandayken çalışması için zamanlayıcıyı nerede başlatıp 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, etkinlik görünür olmaktan çıktıktan sonra çağrılır. Bu geri çağırmalar, zamanlayıcıyı başlatmak ve durdurmak için iyi birer aday gibi görünüyor.
MainActivitysınıfında,onStart()geri çağırma işlevinde zamanlayıcıyı başlatın:
override fun onStart() {
super.onStart()
dessertTimer.startTimer()
Timber.i("onStart called")
}- Zamanlayıcıyı
onStop()içinde durdurma:
override fun onStop() {
super.onStop()
dessertTimer.stopTimer()
Timber.i("onStop Called")
}- Uygulamayı derleyip çalıştırın. Android Studio'da Logcat bölmesini tıklayın. Logcat arama kutusuna
dessertclickergirin. Bu, hemMainActivityhem deDessertTimersınıflarına göre filtreleme yapar. Uygulama başladığında zamanlayıcının da hemen çalışmaya başladığını unutmayın.
- Geri düğmesini tıkladığınızda zamanlayıcının tekrar durduğunu görürsünüz. Hem etkinlik hem de kontrol ettiği zamanlayıcı yok edildiği için zamanlayıcı durur.
- Uygulamaya dönmek için son kullanılanlar ekranını kullanın. Logcat'te zamanlayıcının 0'dan yeniden başladığını fark edin.
- Paylaş düğmesini tıklayın. Logcat'te zamanlayıcının çalışmaya devam ettiğini fark edin.

- Ana Sayfa düğmesini tıklayın. Logcat'te zamanlayıcının çalışmayı durdurduğunu fark edin.
- Uygulamaya dönmek için son kullanılanlar ekranını kullanın. Logcat'te zamanlayıcının kaldığı yerden tekrar başladığını fark edin.
MainActivityiçinde,onStop()yöntemindestopTimer()çağrısını yorum satırı yapın.stopTimer()ifadesini yorum satırı olarak işaretlemek,onStart()içinde bir işlem başlattığınız ancakonStop()içinde tekrar durdurmayı unuttuğunuz durumu gösterir.- Uygulamayı derleyip ç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ışmaya devam eder 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ıdır ve muhtemelen istediğiniz davranış değildir.
Genel olarak, bir geri çağırma işlevinde bir şeyi ayarladığınızda veya başlattığınızda, ilgili geri çağırma işlevinde bu şeyi durdurur veya kaldırırsınız. Böylece, artık gerekmediğinde hiçbir şeyin çalışmasını önleyebilirsiniz.
- Zamanlayıcıyı durdurduğunuz
onStop()satırındaki yorum işaretini kaldırın. startTimer()aralığındakionStart()çağrısını kesiponCreate()aralığına yapıştırın. Bu değişiklik,onCreate()kullanarak başlatmak yerine hemonCreate()içinde bir kaynağı başlattığınız hem de başlattığınız durumu gösterir.onStart()- Uygulamayı derleyip çalıştırın. Zamanlayıcının beklendiği gibi çalışmaya başladığını fark edin.
- Uygulamayı durdurmak için Ana Sayfa'yı tıklayın. Zamanlayıcı, beklendiği gibi durur.
- Uygulamaya dönmek için son kullanılanlar ekranını kullanın. Bu durumda,
onCreate()yalnızca uygulama başlatıldığında çağrıldığı için zamanlayıcının yeniden başlamadığını unutmayın. Uygulama ön plana döndüğünde çağrılmaz.
Hatırlanması gereken önemli noktalar:
- Bir yaşam döngüsü geri çağırma işlevinde kaynak ayarladığınızda kaynağı da kapatın.
- Kurulum ve kaldırma işlemlerini ilgili yöntemlerle yapın.
onStart()'da bir şey ayarladıysanızonStop()'da durdurun veya tekrar kaldırın.
DessertClicker uygulamasında, zamanlayıcıyı onStart() içinde başlattıysanız onStop() içinde durdurmanız gerektiği oldukça kolay bir şekilde anlaşılıyor. Yalnızca bir zamanlayıcı olduğundan zamanlayıcıyı durdurmayı unutmazsınız.
Daha karmaşık bir Android uygulamasında, onStart() veya onCreate() içinde birçok şey ayarlayıp onStop() veya onDestroy() içinde hepsini kaldırabilirsiniz. Örneğin, hem ayarlamanız hem de kaldırmanız, hem başlatmanız hem de durdurmanız gereken animasyonlar, müzikler, sensörler veya zamanlayıcılar olabilir. Birini unutursanız hatalara ve sorunlara yol açarsınız.
Android Jetpack'in bir parçası olan Lifecycle kitaplığı bu görevi kolaylaştırır. Kitaplık, özellikle farklı yaşam döngüsü durumlarında olan birçok hareketli parçayı izlemeniz gerektiğinde yararlıdır. Kitaplık, yaşam döngülerinin çalışma şeklini tersine çevirir: Genellikle etkinlik veya parça, bir yaşam döngüsü geri çağırma işlemi gerçekleştiğinde bir bileşene (ör. DessertTimer) ne yapması gerektiğini söyler. Ancak yaşam döngüsü kitaplığını kullandığınızda bileşen, 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:
- Yaşam döngüsüne sahip olan (ve dolayısıyla "sahibi" olan) bileşenler olan yaşam döngüsü sahipleri.
ActivityveFragment, yaşam döngüsü sahipleridir. Yaşam döngüsü sahipleriLifecycleOwnerarayüzünü uygular. - Yaşam döngüsü sahibinin gerçek durumunu tutan ve yaşam döngüsü değişiklikleri gerçekleştiğinde etkinlikleri tetikleyen
Lifecyclesı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özlemcileri. Yaşam döngüsü gözlemcileri,
LifecycleObserverarayüzünü uygular.
Bu görevde, DessertClicker uygulamasını Android yaşam döngüsü kitaplığını kullanacak şekilde dönüştürecek ve kitaplığın Android etkinliği ve parça yaşam döngüleriyle çalışmayı nasıl kolaylaştırdığını öğreneceksiniz.
1. adım: DessertTimer'ı LifecycleObserver'a dönüştürün
Yaşam döngüsü kitaplığının temel bir parçası yaşam döngüsü gözlemi kavramıdır. Gözlem, sınıfların (ör. DessertTimer) etkinlik veya parça yaşam döngüsü hakkında bilgi edinmesini ve bu yaşam döngüsü durumlarındaki değişikliklere yanıt olarak kendilerini başlatıp durdurmasını sağlar. Yaşam döngüsü gözlemcisiyle, nesneleri başlatma ve durdurma sorumluluğunu etkinlik ve parça yöntemlerinden kaldırabilirsiniz.
DesertTimer.ktsınıfını açın.DessertTimersınıfının sınıf imzasını şu şekilde değiştirin:
class DessertTimer(lifecycle: Lifecycle) : LifecycleObserver {Bu yeni sınıf tanımı iki işlevi yerine getirir:
- Oluşturucu, zamanlayıcının gözlemlediği yaşam döngüsü olan bir
Lifecyclenesnesi alır. - Sınıf tanımı,
LifecycleObserverarayüzünü uygular.
runnabledeğişkeninin altına sınıf tanımına birinitbloğu ekleyin.initbloğunda, sahibinden (etkinlik) iletilen yaşam döngüsü nesnesini bu sınıfa (gözlemci) bağlamak içinaddObserver()yöntemini kullanın.
init {
lifecycle.addObserver(this)
}startTimer()öğesini@OnLifecycleEvent annotationile açıklama olarak ekleyin veON_STARTyaşam döngüsü etkinliğini kullanın. Yaşam döngüsü gözlemcinizin gözlemleyebileceği tüm yaşam döngüsü etkinlikleriLifecycle.Eventsınıfındadır.
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun startTimer() {stopTimer()için de aynı işlemi yapın veON_STOPetkinliğini kullanın:
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun stopTimer()2. adım: MainActivity'yi değiştirin
FragmentActivity üst sınıfı LifecycleOwner'yi uyguladığından MainActivity sınıfınız zaten devralma yoluyla yaşam döngüsü sahibidir. Bu nedenle, etkinliğinizin yaşam döngüsünden haberdar olması için herhangi bir işlem yapmanız gerekmez. Tek yapmanız gereken, etkinliğin yaşam döngüsü nesnesini DessertTimer oluşturucusuna iletmektir.
MainActivityadlı kişiyi aç.onCreate()yönteminde,DessertTimerbaşlatma işleminithis.lifecycle'yi içerecek şekilde değiştirin:
dessertTimer = DessertTimer(this.lifecycle)Etkinliğin lifecycle özelliği, bu etkinliğin sahibi olduğu Lifecycle nesnesini içerir.
onCreate()'dakistartTimer()numaralı telefona yapılan aramayı veonStop()'dakistopTimer()numaralı telefona yapılan aramayı kaldırın.DessertTimerartık yaşam döngüsünü kendisi gözlemlediği ve yaşam döngüsü durumu değiştiğinde otomatik olarak bilgilendirildiği için etkinlikteDessertTimer'ya ne yapması gerektiğini söylemenize gerek yoktur. Bu geri çağırmalarda artık tek yaptığınız işlem mesaj kaydetmektir.- Uygulamayı derleyip çalıştırın ve Logcat'i açın. Zamanlayıcının beklendiği gibi çalışmaya başladığını fark edin.

- Uygulamayı arka plana almak için ana sayfa düğmesini tıklayın. Zamanlayıcının beklendiği gibi durduğunu fark edin.
Android, arka planda çalışan bir uygulamayı kapatırsa uygulamanıza ve verilerine ne olur? Bu zorlu uç durumu anlamak önemlidir.
Uygulamanız arka plana geçtiğinde yok edilmez, yalnızca durdurulur ve kullanıcının uygulamaya dönmesini bekler. Ancak Android işletim sisteminin temel endişelerinden biri, ön plandaki etkinliğin sorunsuz bir şekilde çalışmasını sağlamaktır. Örneğin, kullanıcınız otobüse binmesine yardımcı olması için bir GPS uygulaması kullanıyorsa bu GPS uygulamasını hızlı bir şekilde oluşturmak ve yol tariflerini göstermeye devam etmek önemlidir. Kullanıcının birkaç gündür bakmamış olabileceği DessertClicker uygulamasının arka planda sorunsuz çalışmasını sağlamak daha az önemlidir.
Android, ön plandaki uygulamanın sorunsuz çalışabilmesi için arka plandaki uygulamaları düzenler. Örneğin, Android arka planda çalışan uygulamaların yapabileceği işlem miktarını sınırlar.
Android bazen uygulamanın tüm işlemlerini (uygulamayla ilişkili tüm etkinlikler dahil) kapatır. Android, sistemin zorlandığı ve görsel olarak gecikme tehlikesiyle karşı karşıya olduğu durumlarda bu tür bir kapatma işlemi yapar. Bu nedenle, 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ıya göre uygulama kapatılmamış gibi görünür. Kullanıcı, Android işletim sisteminin kapattığı bir uygulamaya geri döndüğünde Android bu uygulamayı yeniden başlatır.
Bu görevde, bir Android işleminin kapatılmasını simüle edip uygulamanız yeniden başlatıldığında neler olduğunu incelersiniz.
1. adım: İşlem kapatmayı simüle etmek için adb'yi kullanın
Android Debug Bridge (adb), bilgisayarınıza bağlı emülatörlere ve cihazlara talimat göndermenize olanak tanıyan bir komut satırı aracıdır. Bu adımda, uygulamanızın sürecini kapatmak ve Android uygulamanızı kapattığında ne olduğunu görmek için adb aracını kullanırsınız.
- Uygulamanızı derleyip çalıştırın. Cupcake'i birkaç kez tıklayın.
- Uygulamanızı arka plana almak için ana sayfa düğmesine basın. Uygulamanız artık durdurulur ve Android'in uygulamanın kullandığı kaynaklara ihtiyacı olursa uygulama kapatılabilir.
- Android Studio'da komut satırı terminalini açmak için Terminal sekmesini tıklayın.

adbyazıp Return tuşuna basın.Android Debug Bridge version X.XX.Xile başlayıptags to be used by logcat (see logcat —help) ile biten çok sayıda çıktı görüyorsanız her şey yolundadır. Bunun yerineadb: command not foundsimgesini görüyorsanızadbkomutunun yürütme yolunuzda kullanılabilir olduğundan emin olun. Talimatlar için Utilities chapter (Yardımcı Programlar bölümü) içindeki "Add adb to your execution path" (adb'yi yürütme yolunuza ekleme) başlıklı makaleye 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.dessertclickerBu komut, bağlı cihazlara veya emülatörlere dessertclicker paket adıyla işlemi durdurmalarını söyler ancak yalnızca uygulama arka plandaysa. Uygulamanız arka planda olduğundan, işleminizin durdurulduğunu belirten herhangi bir şey cihazda veya emülatör ekranında gösterilmez. Android Studio'da Çalıştır sekmesini tıklayarak "Uygulama sonlandırıldı" mesajını görün. onDestroy() geri çağırma işlevinin hiçbir zaman çalıştırılmadığını (etkinliğinizin sona erdiğini) görmek için Logcat sekmesini tıklayın.
- Uygulamaya dönmek için son kullanılanlar ekranını kullanın. Uygulamanız, arka plana alınmış veya tamamen durdurulmuş olsa da son kullanılanlar ekranında görünür. Uygulamaya dönmek için son kullanılanlar ekranını kullandığınızda etkinlik yeniden başlatılır. 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 "puanınızın" (hem satılan tatlı sayısı hem de toplam tutar) varsayılan değerlere (0) sıfırlandığını unutmayın. Android, uygulamanızı kapattıysa neden durumunuzu kaydetmedi?
İşletim sistemi, uygulamanızı sizin için yeniden başlattığında Android, uygulamanızı önceki durumuna sıfırlamak için elinden geleni yapar. Android, bazı görünümlerinizin durumunu alır ve etkinlikten ayrıldığınızda bunu bir pakete kaydeder. Otomatik olarak kaydedilen verilere örnek olarak EditText'teki metin (düzen içinde bir kimlik ayarlanmış olması koşuluyla) ve etkinliğinizin geri yığını verilebilir.
Ancak Android işletim sistemi bazen tüm verileriniz hakkında bilgi sahibi olmaz. Örneğin, DessertClicker uygulamasındarevenuegibi bir özel değişkeniniz varsa Android işletim sistemi bu veriler veya etkinliğiniz için önemleri hakkında bilgi sahibi değildir. Bu verileri pakete kendiniz eklemeniz gerekir.
2. adım: Paket verilerini kaydetmek için onSaveInstanceState() yöntemini kullanın
onSaveInstanceState() yöntemi, Android işletim sistemi uygulamanızı yok ederse ihtiyacınız olabilecek verileri kaydetmek için kullandığınız geri çağırmadır. Yaşam döngüsü geri çağırma şemasında onSaveInstanceState(), etkinlik durdurulduktan sonra çağrılır. Uygulamanız her arka plana gittiğinde bu işlev çağrılır.

onSaveInstanceState() çağrısını bir güvenlik önlemi olarak düşünebilirsiniz. Etkinliğiniz ön plandan çıktığında küçük bir bilgi miktarını pakete kaydetme fırsatı verir. Sistem, uygulamanızı kapatana kadar beklerse işletim sistemi kaynak baskısı altında kalabileceği için bu verileri şimdi kaydeder. Verilerin her seferinde kaydedilmesi, paketteki güncelleme verilerinin gerektiğinde geri yüklenebilmesini sağlar.
MainActivityiçindeonSaveInstanceState()geri çağırmasını geçersiz kılın veTimbergünlük ifadesi ekleyin.
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
Timber.i("onSaveInstanceState Called")
}- Uygulamayı derleyip çalıştırın ve arka plana almak için Ana Sayfa düğmesini tıklayın.
onSaveInstanceState()geri çağırmasınınonPause()veonStop():
hemen ardından gerçekleştiğini unutmayın. - Dosyanın en üstünde, sınıf tanımından hemen önce şu sabitleri ekleyin:
const val KEY_REVENUE = "revenue_key"
const val KEY_DESSERT_SOLD = "dessert_sold_key"
const val KEY_TIMER_SECONDS = "timer_seconds_key"Bu anahtarları, örnek durumu paketinden veri kaydetmek ve almak için kullanırsınız.
onSaveInstanceState()bölümüne gidin veBundletüründe olanoutStateparametresine dikkat edin.
Paket, anahtarların her zaman dize olduğu bir anahtar/değer çiftleri koleksiyonudur. Paketeintvebooleandeğerleri gibi temel değerler yerleştirebilirsiniz.
Sistem bu paketi RAM'de tuttuğu için paketteki verileri küçük tutmak en iyi uygulamadır. Bu paketin boyutu da sınırlıdır ancak boyutu cihazdan cihaza değişir. Genellikle 100.000'den çok daha az öğe depolamanız gerekir. Aksi takdirde, uygulamanızınTransactionTooLargeExceptionhatasıyla kilitlenmesi riskiyle karşılaşırsınız.onSaveInstanceState()içinde,revenuedeğerini (bir tam sayı)putInt()yöntemiyle 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 sabiti) ve kaydedilecek gerçek değer.
- Satılan tatlı sayısı ve zamanlayıcının durumu için aynı işlemi 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() işlevini kullanın
onCreate()simgesine gidin ve yöntem imzasını inceleyin:
override fun onCreate(savedInstanceState: Bundle) {onCreate() her çağrıldığında Bundle değerini alır. Etkinliğiniz bir işlem kapatma nedeniyle yeniden başlatıldığında, kaydettiğiniz paket onCreate()'a iletilir. Etkinliğiniz yeni başlıyorsa onCreate() içindeki bu paket null. Bu nedenle, paket null değilse etkinliği daha önce bilinen bir noktadan "yeniden oluşturduğunuzu" anlarsınız.
DessertTimerkurulumundan sonraonCreate()'ya ş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 sıfırdan başlatılıp başlatılmadığını ya da kapatıldıktan sonra yeniden oluşturulup oluşturulmadığını gösterir. Bu test, paketten veri geri yüklemek için kullanılan yaygın bir yöntemdir.
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 olarak tanımlamanız önerilir. Verileri pakete yerleştirmek için putInt() kullandığınız gibi, paketten veri almak için getInt() kullanırsınız. getInt() yöntemi iki bağımsız değişken alır:
- Anahtar görevi gören bir dize (ör. gelir değeri için
"key_revenue"). - Pakette bu anahtar için değer yoksa varsayılan değer.
Paketten aldığınız tam sayı daha sonra revenue değişkenine atanır ve kullanıcı arayüzü bu değeri kullanır.
- Satılan tatlı sayısını ve zamanlayıcının değerini geri yüklemek için
getInt()yöntemlerini 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. Cupcake, donut'a dönüşene kadar en az beş kez basın. Uygulamayı arka plana almak için Ana Sayfa'yı tıklayın.
- Uygulamanın sürecini kapatmak için Android Studio Terminal sekmesinde
adbkomutunu çalıştırın.
adb shell am kill com.example.android.dessertclicker- Uygulamaya dönmek için son kullanılanlar ekranını kullanın. Bu kez uygulamanın, paketteki doğru gelir ve satılan tatlı değerleriyle döndüğünü göreceksiniz. Ancak tatlının da keke döndüğünü fark edin. Uygulamanın kapatıldıktan sonra tam olarak bırakıldığı şekilde geri dönmesini sağlamak için yapılması gereken bir işlem daha var.
MainActivitybölümündeshowCurrentDessert()yöntemini inceleyin. Bu yöntemin, satılan tatlıların mevcut sayısına veallDessertsdeğişkenindeki tatlı listesine göre etkinlikte hangi tatlı resminin gösterileceğini belirlediğini unutmayın.
for (dessert in allDesserts) {
if (dessertsSold >= dessert.startProductionAmount) {
newDessert = dessert
}
else break
}Bu yöntemde, doğru resmi seçmek için satılan tatlıların sayısı kullanılır. Bu nedenle, paketteki resme referans depolamak için onSaveInstanceState() içinde herhangi bir işlem yapmanız gerekmez. Bu pakette, satılan tatlıların sayısını zaten saklıyorsunuz.
onCreate()içinde, paketten durumu geri yükleyen bloktashowCurrentDessert()işlevini çağırın:
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 çalıştırın ve arka plana alın. İşlemi kapatmak için
adböğesini kullanın. Uygulamaya dönmek için son kullanılanlar ekranını kullanın. Tatlı siparişleri, toplam gelir ve tatlı resmi değerlerinin doğru şekilde geri yüklendiğini unutmayın.
Etkinlik ve parça yaşam döngüsünü yönetirken anlaşılması gereken son bir özel durum vardır: yapılandırma değişikliklerinin etkinliklerinizin ve parçalarınızın yaşam döngüsünü nasıl etkilediği.
Cihazın durumu o kadar radikal bir şekilde değişir ki sistemin bu değişikliği çözmenin en kolay yolu etkinliği tamamen kapatıp yeniden oluşturmaktır. Bu duruma yapılandırma değişikliği denir. Örneğin, kullanıcı cihaz dilini değiştirirse farklı metin yönlerini desteklemek için tüm düzenin değiştirilmesi gerekebilir. Kullanıcı cihazı bir yerleştirme istasyonuna takarsa veya fiziksel bir klavye eklerse uygulama düzeninin farklı bir ekran boyutundan ya da düzenden yararlanması gerekebilir. Cihaz yönü değişirse (ör. cihaz dikeyden yataya veya yataydan dikeye döndürülürse) düzenin yeni yöne uyacak şekilde değiştirilmesi gerekebilir.
1. adım: Cihaz döndürme 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. Döndürme düğmeleriyle veya
Controlve ok tuşlarıyla (Mac'teCommandve ok tuşları) emülatörü sola veya sağa döndürebilirsiniz.
- Logcat'teki çıkışı inceleyin. Çıkışı
MainActivity'ya göre filtreleyin.
Cihaz veya emülatör ekranı döndürdüğünde sistemin, etkinliği kapatmak için tüm yaşam döngüsü geri çağırmalarını çağırdığını unutmayın. 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. MainActivityiçindeonSaveInstanceState()yönteminin tamamını yorum satırı yapın.- Uygulamanızı tekrar derleyip çalıştırın. 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şlatılır.
Yapılandırma değişikliği gerçekleştiğinde Android, uygulamanın durumunu kaydetmek ve geri yüklemek için önceki görevde öğrendiğiniz aynı örnek durumu paketini kullanır. İşlem kapatma işleminde olduğu gibi, uygulamanızın verilerini pakete yerleştirmek içinonSaveInstanceState()kullanın. Ardından, cihaz döndürülürse etkinlik durumu verilerinin kaybolmasını önlemek içinonCreate()içindeki verileri geri yükleyin. MainActivityiçindeonSaveInstanceState()yönteminin yorumunu kaldırın, uygulamayı çalıştırın, cupcake'i tıklayın ve uygulamayı veya cihazı döndürün. Bu kez tatlı verilerinin etkinlik rotasyonu boyunca korunduğunu fark edin.
Android Studio projesi: DessertClickerFinal
Yaşam döngüsüyle ilgili ipuçları
- Bir yaşam döngüsü geri çağırma işlevinde ayarladığınız veya başlattığınız bir şeyi, ilgili geri çağırma işlevinde durdurun veya kaldırın. Öğeyi durdurarak artık gerekmediğinde çalışmaya devam etmemesini sağlayabilirsiniz. Örneğin,
onStart()uygulamasında bir zamanlayıcı ayarlarsanız zamanlayıcıyıonStop()uygulamasında duraklatmanız veya durdurmanız gerekir. onCreate()işlevini yalnızca uygulamanız ilk başlatıldığında bir kez çalışan kısımlarını başlatmak için kullanın. Uygulamanızın hem başlatıldığında hem de her ön plana döndüğünde çalışan bölümlerini başlatmak içinonStart()kullanın.
Lifecycle kitaplığı
- Yaşam döngüsü kontrolünü etkinlikten 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,
ActivityveFragmentdahil olmak üzere yaşam döngülerine sahip olan (ve dolayısıyla "sahibi" olan) bileşenlerdir. Yaşam döngüsü sahipleriLifecycleOwnerarayüzünü uygular. - Yaşam döngüsü gözlemcileri, 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özlemcileri,
LifecycleObserverarayüzünü uygular. Lifecyclenesneleri 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:
- Yaşam döngüsünün farkında olması gereken sınıflarda
LifecycleObserverarayüzünü uygulayın. - Etkinlik veya parçadaki yaşam döngüsü nesnesiyle bir yaşam döngüsü gözlemcisi sınıfını başlatın.
- Yaşam döngüsü gözlemcisi sınıfında, yaşam döngüsüne duyarlı yöntemleri ilgilendikleri yaşam döngüsü durum değişikliğiyle açıklama ekleyin.
Örneğin,@OnLifecycleEvent(Lifecycle.Event.ON_START)açıklaması, yönteminonStartyaşam döngüsü etkinliğini izlediğini gösterir.
İşlem kapatmaları ve etkinlik durumunu kaydetme
- Android, ön plandaki uygulamanın sorunsuz çalışabilmesi için arka planda çalışan uygulamaları düzenler. Bu düzenleme, arka plandaki uygulamaların yapabileceği işlem miktarını sınırlamayı ve hatta bazen tüm uygulama sürecinizi kapatmayı içerir.
- Kullanıcı, sistemin arka planda bir uygulamayı kapatıp kapatmadığını anlayamaz. Uygulama, son kullanılanlar ekranında görünmeye devam eder ve kullanıcının bıraktığı durumda yeniden başlatılır.
- Android Debug Bridge (
adb), bilgisayarınıza bağlı emülatörlere ve cihazlara talimat göndermenize olanak tanıyan bir komut satırı aracıdır. Uygulamanızda işlem kapatmayı simüle etmek içinadbkullanabilirsiniz. - Android, uygulama işleminizi kapattığında
onDestroy()yaşam döngüsü yöntemi çağrılmaz. Uygulama durur.
Etkinlik ve parça durumunu koruma
- Uygulamanız arka plana gittiğinde,
onStop()çağrıldıktan hemen sonra uygulama verileri bir pakete kaydedilir.EditTextiçeriği gibi bazı uygulama verileri sizin için otomatik olarak kaydedilir. - Paket, anahtar ve değer koleksiyonu olan
Bundleöğesinin bir örneğidir. Anahtarlar her zaman dizedir. - Uygulama otomatik olarak kapatılsa bile saklamak istediğiniz diğer verileri pakete kaydetmek için
onSaveInstanceState()geri çağırma işlevini kullanın. Pakete veri yerleştirmek içinputile başlayan paket yöntemlerini (ör.putInt()) kullanın. - Verileri
onRestoreInstanceState()yöntemiyle veya daha yaygın olarakonCreate()yöntemiyle paketten geri alabilirsiniz.onCreate()yönteminde paketi tutan birsavedInstanceStateparametresi var. savedInstanceStatedeğişkeninulliçeriyorsa etkinlik, durum paketi olmadan başlatılmıştır ve alınacak durum verisi yoktur.- Paketten anahtarla veri almak için
getile başlayanBundleyöntemlerini (ör.getInt()) kullanın.
Yapılandırma değişiklikleri
- Cihazın durumu o kadar radikal bir şekilde değişir ki sistemin bu değişikliği çözmesinin en kolay yolu etkinliği kapatıp yeniden oluşturmaktır. Bu duruma yapılandırma değişikliği denir.
- 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ın dili değiştiğinde veya donanım klavyesi takıldığında da yapılandırma değişikliği olabilir.
- Yapılandırma değişikliği olduğunda Android, etkinlik yaşam döngüsünün tüm kapatma geri çağırmalarını çağırır. Ardından Android, tüm yaşam döngüsü başlangıç geri çağırmalarını çalıştırarak etkinliği baştan başlatır.
- Android, yapılandırma değişikliği nedeniyle bir uygulamayı kapattığında etkinliği
onCreate()için kullanılabilen durum paketiyle yeniden başlatır. - İşlem kapatma işleminde olduğu gibi, uygulamanızın durumunu
onSaveInstanceState()içindeki pakete kaydedin.
Udacity kursu:
Android geliştirici belgeleri:
- 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 İşleme
LifecycleOwnerLifecycleLifecycleObserveronSaveInstanceState()- 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ğitmenin yönettiği kurs kapsamında bu codelab'i tamamlayan öğrenciler için olası ödevler listelenmektedir. Eğitmen, aşağıdakileri yapmalıdır:
- Gerekirse ödev atayın.
- Öğrencilere ev ödevi ödevlerini nasıl göndereceklerini bildirin.
- Ödevlere not verin.
Eğitmenler bu önerileri istedikleri kadar kullanabilir ve uygun olduğunu düşündükleri diğer ödevleri verebilirler.
Bu codelab'i kendi başınıza tamamlıyorsanız bilginizi test etmek için bu ödevleri kullanabilirsiniz.
Uygulamaları değiştirme
1. dersteki DiceRoller uygulamasını açın. (Uygulama yüklü değilse buradan indirebilirsiniz.) Uygulamayı derleyip çalıştırın. Cihazı döndürdüğünüzde zarın geçerli değerinin kaybolduğunu unutmayın. Paketteki değeri korumak ve bu değeri onCreate() içinde geri yüklemek için onSaveInstanceState() öğesini uygulayın.
Bu soruları yanıtlayın
1. Soru
Uygulamanız, gösterilmesi için yoğun hesaplama gerektiren bir fizik simülasyonu içeriyor. Ardından kullanıcı telefonla aranır. Aşağıdaki ifadelerden hangisi doğrudur?
- Telefon görüşmesi sırasında, fizik simülasyonundaki nesnelerin konumlarını hesaplamaya devam etmelisiniz.
- Telefon görüşmesi sırasında, fizik simülasyonundaki nesnelerin konumlarını hesaplamayı durdurmanız gerekir.
2. Soru
Uygulama ekranda olmadığında simülasyonu duraklatmak için hangi yaşam döngüsü yöntemini geçersiz kılmalısınız?
onDestroy()onStop()onPause()onSaveInstanceState()
3. Soru
Android Lifecycle kitaplığı aracılığıyla bir sınıfın yaşam döngüsünden haberdar olmasını sağlamak için sınıf hangi arayüzü uygulamalıdır?
LifecycleLifecycleOwnerLifecycle.EventLifecycleObserver
4. Soru
Etkinliğinizdeki onCreate() yöntemi hangi durumlarda 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.
- Arka plandan döndükten sonra etkinlik devam ettirilir.
- Cihaz yeniden başlatılır.
Bir sonraki derse başlayın:
Bu kurstaki diğer codelab'lerin bağlantılarını Android Kotlin Hakkında Temel Bilgiler codelab'leri açılış sayfasında bulabilirsiniz.