Yapılandırma değişikliklerini işleme

Bazı cihaz yapılandırmaları uygulama çalışırken değişebilir. Bu tür içerikler aşağıdakileri kapsar, ancak bunlarla sınırlı değildir:

  • Uygulama görüntüleme boyutu
  • Ekran yönü
  • Yazı tipi boyutu ve genişliği
  • Yerel ayar
  • Koyu mod ve açık mod
  • Klavye kullanılabilirliği

Bu yapılandırma değişikliklerinin çoğu, bazı kullanıcı etkileşimleri nedeniyle gerçekleşir. Ö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ştirdiğinizde, bu ayarların Configuration nesnesindeki ilgili değerler de değişir.

Bu parametreler genellikle uygulamanızın kullanıcı arayüzünde, değişiklik yapıldığında Android platformunun amaca yönelik bir mekanizmaya sahip olmasını sağlayacak kadar büyük değişiklikler gerektirir. Bu mekanizma Activity yeniden oluşturmadır.

Aktivite ve rekreasyon

Bir yapılandırma değişikliği gerçekleştiğinde sistem bir Activity öğesini yeniden oluşturur. Sistem bunu yapmak için onDestroy() yöntemini çağırır ve mevcut Activity örneğini kaldırır. Daha sonra 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 aynı zamanda sistemin, kullanıcı arayüzünü yeni yapılandırmayla yeniden oluşturacağı anlamına da gelir.

Yeniden oluşturma davranışı, uygulamanızı yeni cihaz yapılandırmasıyla eşleşen 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, mevcut dile bağlı olarak metni tam olarak bir kez ayarlar. Dil değişirse sistem, etkinliği yeniden oluşturur. Sonuç olarak sistem, görünümü de yeniden oluşturur ve yeni dile göre doğru değere başlatır.

Yeniden oluşturma ayrıca Activity içinde veya içerdiği Fragment, View ya da diğer nesnelerde alan olarak tutulan durumları da temizler. Bunun nedeni, Activity yeniden oluşturma işleminin Activity ve kullanıcı arayüzünün tamamen yeni bir örneğini oluşturmasıdır. Dahası, eski Activity artık görünür veya geçerli olmadığından bu öğeye veya içerdiği nesnelere yönelik kalan referanslar eskidir. Bunlar hatalara, bellek sızıntılarına ve kilitlenmelere neden olabilir.

Kullanıcı beklentileri

Bir uygulamanın kullanıcısı, durumun korunmasını bekliyor. Kullanıcı bir form doldururken bilgi referansı için çoklu pencere modunda başka bir uygulama açarsa temizlenmiş bir forma geri dönmesi veya uygulamada tamamen başka bir yere gitmesi kötü bir kullanıcı deneyimi oluşturur. Geliştirici olarak, yapılandırma değişiklikleri ve etkinliği yeniden oluşturma yoluyla tutarlı bir kullanıcı deneyimi sağlamanız gerekir.

Uygulamanızda durumun korunup korunmadığını doğrulamak için hem uygulama ön plan hem de arka plandayken yapılandırma değişikliklerine neden olan işlemler yapabilirsiniz. Bu işlemler aşağıdakileri içerir:

  • Cihazı döndürme
  • Çoklu pencere moduna geçiliyor
  • Çoklu pencere modundayken veya serbest biçimli bir pencerede uygulamayı yeniden boyutlandırma
  • Birden fazla ekrana sahip katlanabilir cihazı katlama
  • Sistem temasını değiştirme (ör. koyu mod veya açık mod)
  • Yazı tipi boyutunu değiştirme
  • Sistem veya uygulama dilini değiştirme
  • Donanım klavyesini bağlama veya klavyesinin bağlantısını kesme
  • Yuvaya bağlanma veya yuvanın bağlantısını kesme

Activity yeniden pazarlama aracılığıyla ilgili durumu korumak için uygulayabileceğiniz üç temel yaklaşım vardır. Hangisinin kullanılacağı, korumak istediğiniz durumun türüne bağlıdır:

  • Karmaşık veya büyük verilerin işlem ölümünü ele almak için yerel kalıcılık. Kalıcı yerel depolama alanları arasında veritabanları veya DataStore yer alır.
  • Kullanıcı uygulamayı aktif olarak kullanırken bellekteki kullanıcı arayüzüyle ilgili durumu yönetmek için ViewModel gibi saklanan nesneler.
  • Sistem tarafından başlatılan işlem ölümünü işlemek ve kullanıcı girişine ya da gezinmesine bağlı olarak geçici durumu korumak için kayıtlı örnek durumu.

Bunların her biriyle ilgili API'ler hakkında ayrıntılı bilgi edinmek ve her birinin uygun olduğu durumlarda Kullanıcı arayüzü durumlarını kaydetme bölümüne bakın.

Aktiviteyi yeniden düzenleme

Belirli yapılandırma değişiklikleri için otomatik etkinlik yeniden oluşturmayı engelleyebilirsiniz. Activity yeniden oluşturma işlemi, kullanıcı arayüzünün ve Activity öğesinden türetilen nesnelerin yeniden oluşturulmasıyla sonuçlanır. Bundan kaçınmak için geçerli nedenleriniz olabilir. Örneğin, belirli bir yapılandırma değişikliği sırasında uygulamanızın kaynakları güncellemesi gerekmiyor veya performansla ilgili bir sınırlamanız olabilir. Bu durumda, yapılandırma değişikliğinin etkinliğinizin kendisi tarafından işlendiğini açıklayabilir 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 yapılandırma türünü AndroidManifest.xml dosyanızdaki <activity> girişinde yer alan android:configChanges öğesine ekleyin. Olası değerler, android:configChanges özelliği belgelerinde görünür.

Aşağıdaki manifest kodu, ekran yönü ve klavye kullanılabilirliği değiştiğinde MyActivity için Activity yeniden oluşturma işlevini 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 her zaman etkinliğin yeniden başlatılmasına neden olur. Bunları 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.

View sistemindeki yapılandırma değişikliklerine tepki verme

View sisteminde, Activity yeniden oluşturma özelliğini devre dışı bıraktığınız bir yapılandırma değişikliği gerçekleştiğinde etkinlik, Activity.onConfigurationChanged() çağrısı alır. Ayrıca, ekli tüm görünümler de View.onConfigurationChanged() çağrısı alır. Sistem, android:configChanges ürününe eklemediğiniz yapılandırma değişiklikleri için 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. Daha 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, kaynakları yeni yapılandırmaya göre döndürecek şekilde güncellenir. Bu sayede, sistem etkinliğinizi yeniden başlatmadan kullanıcı arayüzünüzü sıfırlayabilirsiniz.

Örneğin, aşağıdaki onConfigurationChanged() uygulaması bir klavyenin 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() özelliğini uygulayamazsınız. 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ı önlenir. Örneğin, bir TV uygulaması Bluetooth klavye bağlandığında veya çıkarıldığında tepki vermek istemeyebilir.

Durumu koru

Bu tekniği kullanırken normal etkinlik yaşam döngüsü boyunca durumu yine de korumanız gerekir. Bunun nedeni aşağıdakilerden biridir:

  • Kaçınılmaz değişiklikler: Önleyemediğiniz yapılandırma değişiklikleri uygulamanızı yeniden başlatabilir.
  • İşlem ölümü: Uygulamanız, sistem tarafından başlatılan işlem ölümünü işleyebilmelidir. Kullanıcı uygulamanızdan ayrılır ve uygulama arka plana giderse sistem uygulamayı kaldırabilir.
sırasında her kaynağı her bir öğeye yeniden atamanız gerekir.

Jetpack Compose'daki 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 olduğunda tüm yapılandırma değişiklikleri için Activity yeniden pazarlamasını devre dışı bırakırsanız uygulamanızın yapılandırma değişikliklerini doğru şekilde işlemeye devam etmesi gerekir.

Configuration nesnesi, LocalConfiguration bileşimi yerel olarak Compose kullanıcı arayüzü hiyerarşisinde bulunur. Her değişiklik yapıldığında LocalConfiguration.current öğesinden okuma yapan composable işlevler yeniden oluşturulur. Beste yerellerinin işleyiş şekli hakkında bilgi edinmek için CompositionLocal ile yerel kapsamlı veriler bölümüne bakın.

Örnek

Aşağıdaki örnekte, bir composable belirli biçimde bir tarih gösterir. composable, LocalConfiguration.current ile ConfigurationCompat.getLocales() çağrısı yaparak sistem yerel ayar 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 ürününün yeniden oluşturulmaması için, Oluşturma kodunu barındıran Activity, yerel ayar değişikliklerini devre dışı bırakmalıdır. Bunun için android:configChanges değerini locale|layoutDirection olarak ayarlamanız gerekir.

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 (ör. uygulama görüntüleme boyutu, yerel ayar veya sistem teması) tanımlar.
  • Yapılandırma değişiklikleri: Yapılandırmalar kullanıcı etkileşimi yoluyla değişir. Örneğin, kullanıcı cihaz ayarlarını veya cihazla fiziksel olarak nasıl etkileşimde bulunduğunu değiştirebilir. Yapılandırma değişikliklerini önlemek mümkün değildir.
  • Activity yeniden oluşturma: Yapılandırma değişiklikleri, varsayılan olarak Activity yeniden oluşturulmasıyla sonuçlanır. Bu, yeni yapılandırmada uygulama durumunu yeniden başlatmak için kullanılan yerleşik bir mekanizmadır.
  • Activity'nin kaldırılması: Activity yeniden oluşturma, sistemin eski Activity örneğini kaldırmasına ve bunun yerine yeni bir örnek oluşturmasına neden olur. Eski örnek geçerliliğini yitirdi. Bu öğeye yapılan kalan referanslar bellek sızıntılarına, hatalara veya kilitlenmelere neden olur.
  • Durum: Eski Activity örneğindeki durum, iki farklı nesne örneği olduğu için yeni Activity örneğinde mevcut değil. Uygulamayı 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 etkinliği yeniden oluşturma özelliğinin devre dışı bırakılması olası bir optimizasyondur. Uygulamanızın yeni yapılandırmaya göre doğru şekilde güncellenmesi gerekir.

İyi bir kullanıcı deneyimi sağlamak için aşağıdaki en iyi uygulamaları dikkate alın:

  • Sık yapılan yapılandırma değişikliklerine hazırlıklı olun: API düzeyi, form faktörü veya kullanıcı arayüzü araç seti ne olursa olsun yapılandırma değişikliklerinin nadiren gerçekleştiğini veya hiçbir zaman gerçekleşmeyeceğini varsaymayın. Bir kullanıcı, yapılandırma değişikliğine neden olduğunda uygulamaların güncellenmesini ve yeni yapılandırmayla düzgün şekilde çalışmaya devam etmesini bekler.
  • Durumu koru: Activity yeniden oluşturulduğunda kullanıcının durumunu kaybetmeyin. Durumu, Kullanıcı arayüzü durumlarını kaydetme bölümünde açıklandığı gibi koruyun.
  • Hızlı bir çözüm olarak devre dışı bırakmayın: Durum kaybını önlemek için kısayol olarak Activity yeniden oluşturma özelliğini devre dışı bırakmayın. Etkinlik yeniden oluşturmayı devre dışı bırakmak, değişikliği ele alma vaadini yerine getirmenizi gerektirir. Ayrıca diğer yapılandırma değişikliklerinden kaynaklanan Activity yeniden oluşturma, işleme konması veya uygulamanın kapatılması nedeniyle yine de durumu kaybedebilirsiniz. Activity öğesi oluşturma işlemini tamamen devre dışı bırakmak mümkün değildir. Durumu, Kullanıcı arayüzü durumlarını kaydetme bölümünde açıklandığı gibi koruyun.
  • Yapılandırma değişikliklerinden kaçınmayın: Yapılandırma değişikliklerini ve Activity yeniden oluşturma işlemlerini önlemek için yön, en boy oranı veya yeniden boyutlanabilirlikle ilgili 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. Bu değişiklikler, uygulamanız kullanıcıların çoklu pencere moduna girebileceği büyük ekranlı bir cihazda çalıştığında daha olasıdır. Uygulamanızın bu ortamda iyi çalışmasını beklerler.

Genel olarak iki tür boyut değişikliği vardır: önemli ve önemsiz. Ekran boyutundaki farklılık (ör. genişlik, yükseklik veya en küçük genişlik) nedeniyle, yeni yapılandırmaya farklı bir alternatif kaynak grubunun uygulandığı önemli bir boyut değişikliğidir. Bu kaynaklar, uygulamanın kendisini tanımladığı ve kitaplığının herhangi birindeki kaynaklardır.

Boyuta dayalı yapılandırma değişiklikleri için etkinlik yeniden oluşturmayı 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 öğesini yeniden oluşturmaz. Bunun yerine, Activity.onConfigurationChanged() numarasına bir çağrı alır. Ekteki görünümler View.onConfigurationChanged() çağrısı alır.

Manifest dosyanızda android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout" varsa boyuta dayalı yapılandırma değişiklikleri için Activity yeniden oluşturma 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 önemli olduğunda boyuta dayalı yapılandırma değişiklikleri için gerçekleşir. Sistem, yetersiz boyut nedeniyle bir Activity yeniden oluşturmazsa bunun yerine Activity.onConfigurationChanged() ve View.onConfigurationChanged() çağrılarını yapabilir.

Activity yeniden oluşturulmadığında Activity ve View geri çağırmalarıyla ilgili olarak dikkate alınması gereken bazı uyarılar vardır:

  • Android 11 (API düzeyi 30) ile Android 13 (API düzeyi 33) arasındaki sürümlerde Activity.onConfigurationChanged() çağrılmaz.
  • Android 12L'de (API düzeyi 32) ve Android 13'ün (API düzeyi 33) önceki sürümlerinde bazı durumlarda View.onConfigurationChanged() işlevinin çağrılmamasına yol açan bilinen bir sorun vardır. Daha fazla bilgi için bu herkese açık soruna göz atın. Bu sorun daha sonraki Android 13 sürümlerinde ve Android 14'te giderilmiştir.

Boyuta dayalı yapılandırma değişikliklerini dinlemeye bağlı kodlar için Activity yeniden oluşturma veya Activity.onConfigurationChanged() özelliklerine güvenmek yerine geçersiz kılınmış View.onConfigurationChanged() içeren bir View yardımcı programı kullanmanızı öneririz.