Uygulama çalışırken bazı cihaz yapılandırmaları değişebilir. Aşağıdakilerle sınırlı olmamakla birlikte bu önlemlerden bazıları şunlardır:
- Uygulama görüntüleme boyutu
- Ekran yönlendirme
- Yazı tipi boyutu ve ağırlığı
- Yerel ayar
- Koyu mod ve açık mod
- Klavye kullanılabilirliği
Bu yapılandırma değişikliklerinin çoğu, kullanıcı etkileşiminden kaynaklanır. Örneğin, cihazı döndürmek veya katlamak, uygulamanızın kullanabileceği ekran alanını değiştirir. Benzer şekilde, yazı tipi boyutu, dil veya tercih edilen tema gibi cihaz ayarlarını değiştirmek, Configuration nesnesindeki ilgili değerleri değiştirir.
Bu parametreler genellikle uygulamanızın kullanıcı arayüzünde, Android platformunun değiştiğinde kullanacağı amaca yönelik bir mekanizma oluşturmak için yeterince büyük değişiklikler yapılmasını gerektirir.
Bu mekanizma Activity yeniden oluşturma işlemidir.
Etkinlikleri yeniden oluşturma
Sistem, yapılandırma değişikliği olduğunda Activity öğesini yeniden oluşturur. Bunu yapmak için sistem, onDestroy() işlevini çağırır ve mevcut Activity örneğini yok eder. Ardından, onCreate() kullanarak yeni bir örnek oluşturur ve bu yeni Activity örneği, yeni ve güncellenmiş yapılandırmayla başlatılır. Bu, sistemin kullanıcı arayüzünü yeni yapılandırmayla yeniden oluşturduğu anlamına da gelir.
Yeniden oluşturma davranışı, uygulamanızı yeni cihaz yapılandırmasına uygun alternatif kaynaklarla otomatik olarak yeniden yükleyerek uygulamanızın yeni yapılandırmalara uyum sağlamasına yardımcı olur.
Rekreasyon örneği
Bir düzen XML dosyasında tanımlandığı gibi android:text="@string/title" kullanarak statik bir başlık görüntüleyen bir TextView düşünün. Görünüm oluşturulduğunda, metin geçerli dile göre tam olarak bir kez ayarlanır. Dil değişirse sistem etkinliği yeniden oluşturur. Sonuç olarak sistem, görünümü yeniden oluşturur ve yeni dile göre doğru değerle başlatır.
Yeniden oluşturma işlemi, Activity içinde veya içerdiği Fragment, View ya da diğer nesnelerde alan olarak tutulan tüm durumları da temizler. Bunun nedeni, Activity yeniden oluşturulduğunda Activity ve kullanıcı arayüzünün tamamen yeni bir örneğinin oluşturulmasıdır. Ayrıca, eski Activity artık görünür veya geçerli olmadığından, buna ya da içerdiği nesnelere yapılan tüm referanslar güncel değildir. Hatalara, bellek sızıntılarına ve çökmelere neden olabilirler.
Kullanıcı beklentileri
Bir uygulamanın kullanıcısı, durumun korunmasını bekler. Bir kullanıcı form doldururken bilgi almak için çoklu pencere modunda başka bir uygulama açarsa temizlenmiş bir forma veya uygulamanın tamamen başka bir bölümüne dönmesi kötü bir kullanıcı deneyimidir. Geliştirici olarak, yapılandırma değişiklikleri ve etkinliğin yeniden oluşturulması yoluyla tutarlı bir kullanıcı deneyimi sağlamanız gerekir.
Uygulamanızda durumun korunup korunmadığını doğrulamak için hem uygulama ön plandayken hem de arka plandayken yapılandırma değişikliklerine neden olan işlemler gerçekleştirebilirsiniz. Bu işlemler aşağıdakileri içerir:
- Cihazı döndürme
- Çoklu pencere moduna girme
- Çoklu pencere modunda veya serbest biçimli penceredeyken uygulamayı yeniden boyutlandırma
- Birden fazla ekranı olan katlanabilir bir cihazı katlama
- Sistem temasını değiştirme (ör. koyu mod ve açık mod)
- Yazı tipi boyutunu değiştirme
- Sistem veya uygulama dilini değiştirme
- Donanım klavyesini bağlama veya bağlantısını kaldırma
- Bağlantı istasyonu bağlama veya bağlantısını kaldırma
Activity yeniden oluşturma işlemi sırasında ilgili durumu korumak için kullanabileceğiniz üç temel yaklaşım vardır. Hangisinin kullanılacağı, korumak istediğiniz durum türüne bağlıdır:
- Karmaşık veya büyük verilerde işlem sonlandırmayı yönetmek için yerel kalıcılık.
Kalıcı yerel depolama alanı, veritabanlarını veya
DataStore'ı içerir. - Kullanıcı uygulamayı etkin olarak kullanırken kullanıcı arayüzüyle ilgili durumu bellekte işlemek için
ViewModelörnekleri gibi saklanan nesneler. - Sistem tarafından başlatılan işlem sonlandırmayı işlemek ve kullanıcı girişine veya gezinmeye bağlı geçici durumu korumak için kaydedilmiş örnek durumu.
Bunların her birine yönelik API'ler ve her birinin ne zaman kullanılması gerektiği hakkında ayrıntılı bilgi için Kullanıcı arayüzü durumlarını kaydetme başlıklı makaleyi inceleyin.
Etkinlik yeniden oluşturmayı kısıtlama
Belirli yapılandırma değişiklikleri için otomatik etkinlik yeniden oluşturmayı engelleyebilirsiniz.
Activity yeniden oluşturulduğunda kullanıcı arayüzünün tamamı ve Activity öğesinden türetilen tüm nesneler yeniden oluşturulur. Bunu yapmaktan kaçınmak için geçerli nedenleriniz olabilir. Örneğin, uygulamanızın belirli bir yapılandırma değişikliği sırasında kaynakları güncellemesi gerekmeyebilir veya performans sınırlaması olabilir. Bu durumda, etkinliğinizin yapılandırma değişikliğini kendisinin işlediğini belirtebilir ve sistemin etkinliğinizi yeniden başlatmasını önleyebilirsiniz.
Belirli yapılandırma değişiklikleri için etkinlik yeniden oluşturmayı devre dışı bırakmak istiyorsanız AndroidManifest.xml dosyanızdaki <activity> girişinde yapılandırma türünü android:configChanges'ya ekleyin. Olası değerler, android:configChanges özelliğiyle ilgili dokümanlarda yer alır.
Aşağıdaki manifest kodu, ekran yönü ve klavye kullanılabilirliği değiştiğinde Activity için MyActivity yeniden oluşturmayı devre dışı bırakır:
<activity
android:name=".MyActivity"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
android:label="@string/app_name">
Bazı yapılandırma değişiklikleri, etkinliğin her zaman yeniden başlatılmasına neden olur. Bu bildirimleri devre dışı bırakamazsınız. Örneğin, Android 12L'de (API düzeyi 32) kullanıma sunulan dinamik renk değişikliğini devre dışı bırakamazsınız.
Görünüm sistemindeki yapılandırma değişikliklerine tepki verme
View sisteminde, Activity yeniden oluşturmayı devre dışı bıraktığınız bir yapılandırma değişikliği gerçekleştiğinde etkinlik, Activity.onConfigurationChanged() için bir çağrı alır. Eklenen görünümler de View.onConfigurationChanged() çağrısı alır. android:configChanges'ya eklemediğiniz yapılandırma değişiklikleri için sistem, etkinliği her zamanki gibi yeniden oluşturur.
onConfigurationChanged() geri çağırma yöntemi, yeni cihaz yapılandırmasını belirten bir Configuration nesnesi alır. Yeni yapılandırmanızın ne olduğunu belirlemek için Configuration nesnesindeki alanları okuyun. Sonraki değişiklikleri yapmak için arayüzünüzde kullandığınız kaynakları güncelleyin. Sistem bu yöntemi çağırdığında etkinliğinizin Resources nesnesi, yeni yapılandırmaya göre kaynak döndürecek şekilde güncellenir. Bu sayede, sistem etkinliğinizi yeniden başlatmadan kullanıcı arayüzünüzün öğelerini sıfırlayabilirsiniz.
Örneğin, aşağıdaki onConfigurationChanged() uygulaması, klavye olup olmadığını kontrol eder:
Kotlin
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
// Checks whether a keyboard is available
if (newConfig.keyboardHidden === Configuration.KEYBOARDHIDDEN_YES) {
Toast.makeText(this, "Keyboard available", Toast.LENGTH_SHORT).show()
} else if (newConfig.keyboardHidden === Configuration.KEYBOARDHIDDEN_NO) {
Toast.makeText(this, "No keyboard", Toast.LENGTH_SHORT).show()
}
}
Java
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks whether a keyboard is available
if (newConfig.keyboardHidden == Configuration.KEYBOARDHIDDEN_YES) {
Toast.makeText(this, "Keyboard available", Toast.LENGTH_SHORT).show();
} else if (newConfig.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO){
Toast.makeText(this, "No keyboard", Toast.LENGTH_SHORT).show();
}
}
Uygulamanızı bu yapılandırma değişikliklerine göre güncellemeniz gerekmiyorsa onConfigurationChanged()'yı uygulamayabilirsiniz. Bu durumda, yapılandırma değişikliğinden önce kullanılan tüm kaynaklar kullanılmaya devam eder ve yalnızca etkinliğinizin yeniden başlatılmasını önlemiş olursunuz. Örneğin, bir TV uygulaması, Bluetooth klavye bağlandığında veya ayrıldığında tepki vermek istemeyebilir.
Durumu koruma
Bu tekniği kullandığınızda normal etkinlik yaşam döngüsü sırasında durumu korumanız gerekir. Bunun nedeni aşağıdakilerden biri olabilir:
- Kaçınılmaz değişiklikler: Önleyemediğiniz yapılandırma değişiklikleri uygulamanızı yeniden başlatabilir.
- İşlem sonlandırma: Uygulamanız, sistem tarafından başlatılan işlem sonlandırmayı işleyebilmelidir. Kullanıcı uygulamanızdan ayrılırsa ve uygulama arka plana giderse sistem uygulamayı kaldırabilir.
Jetpack Compose'da yapılandırma değişikliklerine tepki verme
Jetpack Compose, uygulamanızın yapılandırma değişikliklerine daha kolay tepki vermesini sağlar.
Ancak, mümkün olan tüm yapılandırma değişiklikleri için Activity yeniden oluşturmayı devre dışı bırakırsanız uygulamanız yine de yapılandırma değişikliklerini doğru şekilde işlemelidir.
Configuration nesnesi, LocalConfiguration kompozisyon yereliyle birlikte Compose kullanıcı arayüzü hiyerarşisinde kullanılabilir. Değiştiğinde, LocalConfiguration.current öğesinden okuma yapan composable işlevler yeniden oluşturulur. CompositionLocal'lerin işleyiş şekli hakkında bilgi edinmek için CompositionLocal ile yerel kapsamlı veriler başlıklı makaleyi inceleyin.
Örnek
Aşağıdaki örnekte, belirli bir biçimde tarih gösteren bir composable yer almaktadır.
Composable, LocalConfiguration.current ile ConfigurationCompat.getLocales() işlevini çağırarak sistem yerel ayarı yapılandırma değişikliklerine tepki verir.
@Composable
fun DateText(year: Int, dayOfYear: Int) {
val dateTimeFormatter = DateTimeFormatter.ofPattern(
"MMM dd",
ConfigurationCompat.getLocales(LocalConfiguration.current)[0]
)
Text(
dateTimeFormatter.format(LocalDate.ofYearDay(year, dayOfYear))
)
}
Yerel ayar değiştiğinde Activity yeniden oluşturulmasını önlemek için Compose kodunu barındıran Activity, yerel ayar yapılandırma değişikliklerini devre dışı bırakmalıdır. Bunun için android:configChanges ayarını locale|layoutDirection olarak belirleyin.
Yapılandırma değişiklikleri: Temel kavramlar ve en iyi uygulamalar
Yapılandırma değişiklikleri üzerinde çalışırken bilmeniz gereken temel kavramlar şunlardır:
- Yapılandırmalar: Cihaz yapılandırmaları, kullanıcı arayüzünün kullanıcıya nasıl gösterileceğini tanımlar. Örneğin, uygulama görüntüleme boyutu, yerel ayar veya sistem teması.
- Yapılandırma değişiklikleri: Yapılandırmalar, kullanıcı etkileşimiyle değişir. Örneğin, kullanıcı cihaz ayarlarını veya cihazla fiziksel olarak etkileşim kurma şeklini değiştirebilir. Yapılandırma değişikliklerini önlemenin bir yolu yoktur.
Activityyeniden oluşturma: Yapılandırma değişiklikleri varsayılan olarakActivityyeniden oluşturmayla sonuçlanır. Bu, yeni yapılandırma için uygulama durumunu yeniden başlatmaya yönelik yerleşik bir mekanizmadır.Activitydestruction:Activityyeniden oluşturma, sistemin eskiActivityörneğini yok etmesine ve yerine yeni bir örnek oluşturmasına neden olur. Eski örnek artık kullanılmıyor. Bu nesneye yapılan tüm referanslar bellek sızıntılarına, hatalara veya çökmelere neden olur.- Durum: Eski
Activityörneğindeki durum, iki farklı nesne örneği oldukları için yeniActivityörneğinde mevcut değildir. Uygulamanın ve kullanıcının durumunu Kullanıcı arayüzü durumlarını kaydetme bölümünde açıklandığı şekilde koruyun. - Devre dışı bırakma: Bir yapılandırma değişikliği türü için etkinlik yeniden oluşturmayı devre dışı bırakmak olası bir optimizasyondur. Uygulamanızın yeni yapılandırmaya uygun şekilde güncellenmesi gerekir.
İyi bir kullanıcı deneyimi sunmak için aşağıdaki en iyi uygulamalara uyun:
- Sık yapılandırma değişikliklerine hazırlıklı olun: API düzeyi, form faktörü veya kullanıcı arayüzü araç setinden bağımsız olarak yapılandırma değişikliklerinin nadir olduğunu ya da hiç gerçekleşmeyeceğini varsaymayın. Kullanıcılar bir yapılandırma değişikliğine neden olduğunda uygulamaların güncellenmesini ve yeni yapılandırmayla doğru şekilde çalışmaya devam etmesini bekler.
- Durumu koruma:
Activityyeniden oluşturma işlemi gerçekleştiğinde kullanıcının durumunu kaybetmeyin. Durumu Kullanıcı arayüzü durumlarını kaydetme bölümünde açıklandığı şekilde koruyun. - Hızlı çözüm olarak devre dışı bırakmaktan kaçının: Durum kaybını önlemek için
Activityyeniden oluşturma özelliğini devre dışı bırakmayın. Etkinlik yeniden oluşturma özelliğini devre dışı bırakmak için değişikliği işleme sözünüzü tutmanız gerekir. Diğer yapılandırma değişikliklerinden, işlemin sonlandırılmasından veya uygulamanın kapatılmasından kaynaklananActivityyeniden oluşturma nedeniyle durumu yine de kaybedebilirsiniz.Activityyeniden oluşturma özelliğini tamamen devre dışı bırakmak mümkün değildir. Durumu Kullanıcı arayüzü durumlarını kaydetme bölümünde açıklandığı şekilde koruyun. - Yapılandırma değişikliklerinden kaçınmayın: Yapılandırma değişikliklerinden ve
Activityyeniden oluşturulmasından kaçınmak için yönlendirme, en-boy oranı veya yeniden boyutlandırılabilme konusunda kısıtlamalar uygulamayın. Bu durum, uygulamanızı tercih ettikleri şekilde kullanmak isteyen kullanıcıları olumsuz etkiler.
Boyuta dayalı yapılandırma değişikliklerini işleme
Boyuta dayalı yapılandırma değişiklikleri herhangi bir zamanda gerçekleşebilir ve kullanıcıların çoklu pencere moduna girebileceği büyük ekranlı bir cihazda uygulamanız çalışırken daha olasıdır. Uygulamanızın bu ortamda iyi çalışmasını beklerler.
Boyut değişiklikleri genel olarak iki türde olur: önemli ve önemsiz. Önemli boyut değişikliği, ekran boyutundaki (ör. genişlik, yükseklik veya en küçük genişlik) farklılık nedeniyle yeni yapılandırmada farklı bir alternatif kaynak grubunun geçerli olduğu değişikliktir. Bu kaynaklar arasında uygulamanın kendisinin tanımladığı kaynaklar ve kitaplıklarındaki kaynaklar yer alır.
Boyuta dayalı yapılandırma değişiklikleri için etkinliğin yeniden oluşturulmasını kısıtlama
Boyuta dayalı yapılandırma değişiklikleri için Activity yeniden oluşturmayı devre dışı bıraktığınızda sistem Activity yeniden oluşturmaz. Bunun yerine, Activity.onConfigurationChanged() numarasına yapılan bir arama alır. Eklenen tüm görünümler View.onConfigurationChanged() numaralı telefondan aranır.
Manifest dosyanızda android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout" olduğunda, boyuta dayalı yapılandırma değişiklikleri için Activity yeniden oluşturma özelliği devre dışı bırakılır.
Boyuta dayalı yapılandırma değişiklikleri için etkinlik yeniden oluşturmaya izin ver
Android 7.0 (API düzeyi 24) ve sonraki sürümlerde, Activity yeniden oluşturma yalnızca boyut değişikliği önemliyse boyuta dayalı yapılandırma değişiklikleri için gerçekleşir. Sistem, yetersiz boyut nedeniyle Activity öğesini yeniden oluşturmadığında bunun yerine Activity.onConfigurationChanged() ve View.onConfigurationChanged() öğelerini çağırabilir.
Activity yeniden oluşturulmadığında Activity ve View geri çağırmalarıyla ilgili olarak dikkat edilmesi gereken bazı noktalar vardır:
- Android 11 (API düzeyi 30) ile Android 13 (API düzeyi 33) sürümlerinde
Activity.onConfigurationChanged()çağrılmaz. - Android 12L (API düzeyi 32) ve Android 13'ün (API düzeyi 33) ilk sürümlerinde bazı durumlarda
View.onConfigurationChanged()işlevinin çağrılmayabildiği bilinen bir sorun vardır. Daha fazla bilgi için bu herkese açık sorunu inceleyin. Bu sorun, sonraki Android 13 sürümlerinde ve Android 14'te giderilmiştir.
Boyuta dayalı yapılandırma değişikliklerini dinlemeye bağlı olan kod için Activity yeniden oluşturma veya Activity.onConfigurationChanged() işlemine güvenmek yerine geçersiz kılınmış View ile bir yardımcı program View.onConfigurationChanged() kullanmanızı öneririz.