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

Bazı cihaz yapılandırmaları, uygulama çalışırken değişebilir. Bunlardan bazıları şunlardır:

  • Uygulama görüntüleme boyutu
  • Ekran yönü
  • Yazı tipi boyutu ve genişliği
  • Yerel ayar
  • Koyu mod ile açık mod karşılaştırması
  • 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ı miktarı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ğerlerini de değiştirir.

Bu parametreler genellikle uygulamanızın kullanıcı arayüzünde, Android platformunun değişiklik olduğunda amaca yönelik bir mekanizmaya sahip olması için yeterince büyük değişiklikler gerektirir. Bu mekanizma, Activity yeniden oluşturma işlevidir.

Aktivite rekreasyon

Bir yapılandırma değişikliği gerçekleştiğinde sistem bir Activity dosyasını yeniden oluşturur. Bunu yapmak için sistem onDestroy() yöntemini çağırır ve mevcut Activity örneğini kaldırır. Ardından onCreate() kullanarak yeni bir örnek oluşturur ve bu yeni Activity örneği güncellenmiş yeni yapılandırmayla başlatılır. Bu, sistemin ayrıca kullanıcı arayüzünü yeni yapılandırmayla yeniden oluşturması 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 başlık görüntüleyen bir TextView düşünün. Görünüm oluşturulduğunda, mevcut dile göre metni tam olarak bir kez ayarlar. Dil değişirse sistem, etkinliği yeniden oluşturur. Sonuç olarak, sistem de görünümü yeniden oluşturur ve yeni dile göre görünümü doğru değere başlatır.

Etkinlik, Activity içinde veya içerdiği Fragment, View ya da diğer nesnelerden herhangi birinde alan olarak saklanan 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. Ayrıca, eski Activity artık görünür veya geçerli olmadığından bu öğeye veya içerdiği nesnelere geri kalan referanslar eskidir. Hatalara, bellek sızıntılarına ve kilitlenmelere neden olabilirler.

Kullanıcı beklentileri

Bir uygulamanın kullanıcısı, durumun korunmasını bekler. Bir kullanıcı form doldururken bilgilere referans olması için çoklu pencere modunda başka bir uygulamayı açarsa temizlenmiş bir forma veya uygulamada tamamen başka bir yere geri dönmesi kötü bir kullanıcı deneyimi oluşturur. Geliştirici olarak, yapılandırma değişiklikleri ve etkinlik 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 gerçekleştirebilirsiniz. Bu işlemler aşağıdakileri içerir:

  • Cihazı döndürme
  • Çoklu pencere moduna geçiliyor
  • Çoklu pencere modundayken veya serbest biçimli pencerede uygulamayı yeniden boyutlandırma
  • Birden fazla ekranı olan katlanabilir 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 klavye bağlantısını kesme
  • Bir yuvayı bağlama veya yuvanın bağlantısını kesme

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

  • Karmaşık veya büyük verilerde işlem sonlandırmayı ele almak için yerel süreklilik. Kalıcı yerel depolama alanına veritabanları veya DataStore dahildir.
  • Kullanıcı uygulamayı aktif olarak kullanırken bellekte kullanıcı arayüzü ile ilgili durumu işlemek için ViewModel örnekleri gibi tutulan nesneler.
  • Sistem tarafından başlatılan işlem ölümünü yönetmek ve kullanıcı girişine veya gezinmeye bağlı olarak geçici durumu korumak için kayıtlı örnek durumu.

Bunların her birine ait API'ler hakkında ayrıntılı bilgi edinmek ve bunların her birinin hangi durumlarda uygun olduğunu öğrenmek için Kullanıcı arayüzü durumlarını kaydetme bölümüne bakın.

Rekreasyon aktivitesini kısıtla

Belirli yapılandırma değişiklikleri için otomatik etkinlik yeniden oluşturulmasını engelleyebilirsiniz. Activity yeniden oluşturma işlemi, kullanıcı arayüzünün tamamı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 gerekmeyebilir veya performans sınırlandırmanız olabilir. Bu durumda, etkinliğinizin yapılandırma değişikliğini bizzat gerçekleştirdiğini ve sistemin, etkinliğinizi yeniden başlatmasını engellediğini beyan edebilirsiniz.

Belirli yapılandırma değişiklikleri için etkinlik yeniden oluşturma özelliğini devre dışı bırakmak üzere yapılandırma türünü AndroidManifest.xml dosyanızdaki <activity> girişine android:configChanges ekleyin. Olası değerler, android:configChanges özelliğiyle ilgili dokümanlarda verilmiştir.

Aşağıdaki manifest kodu, ekran yönü ve klavye kullanılabilirliği değiştiğinde MyActivity için Activity 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 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şturmayı devre dışı bıraktığınız bir yapılandırma değişikliği gerçekleştiğinde, etkinlik bir Activity.onConfigurationChanged() çağrısı alır. Ayrıca, eklenen tüm görünümler View.onConfigurationChanged() numarasına çağrı alır. android:configChanges ürününe 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ı 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 şekilde, sistem etkinliğinizi yeniden başlatmadan kullanıcı arayüzünüzün öğelerini sıfırlayabilirsiniz.

Örneğin, aşağıdaki onConfigurationChanged() uygulaması, klavyenin mevcut 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önergesini 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ını önlemiş olursunuz. Örneğin, bir TV uygulaması, Bluetooth klavye takıldığında veya çıkarıldığında tepki vermek istemeyebilir.

Durumu koru

Bu tekniği kullandığınızda, normal etkinlik yaşam döngüsü sırasında durumu yine de korumanız gerekir. Bunun nedeni aşağıdakilerden hangisidir:

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

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 olduğunda tüm yapılandırma değişiklikleri için Activity yeniden oluşturmayı devre dışı bırakırsanız uygulamanızın yapılandırma değişikliklerini doğru şekilde işlemesi gerekir.

Configuration nesnesi, Compose kullanıcı arayüzü hiyerarşisinde LocalConfiguration besteyle yerel olarak kullanılabilir. Değer değiştiğinde, LocalConfiguration.current tarihinden itibaren okunan birleştirilen işlevler yeniden oluşturulur. Beste yerellerinin işleyiş şekli hakkında daha fazla bilgi için CompositionLocal ile yerel olarak kapsama alınmış veriler konusuna bakın.

Örnek

Aşağıdaki örnekte, bir composable, belirli bir biçime sahip tarihi görüntüler. Oluşturulabilir, LocalConfiguration.current ile ConfigurationCompat.getLocales() çağırarak sistem yerel ayar yapılandırması 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ş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 öğesini locale|layoutDirection olarak ayarlayın.

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 etkileşimde bulunma şeklini değiştirebilir. Yapılandırma değişikliklerini engellemenin bir yolu yoktur.
  • Activity yeniden oluşturma: Yapılandırma değişiklikleri, varsayılan olarak Activity yeniden oluşturma işlemiyle sonuçlanır. Bu, yeni yapılandırma için uygulama durumunu yeniden başlatmak için kullanılabilecek yerleşik bir mekanizmadır.
  • Activity yok etme: Activity yeniden oluşturma, sistemin eski Activity örneğini yok etmesine ve onun yerine yeni bir örnek oluşturmasına neden olur. Eski örnek artık kullanılmamaktadır. Kalan referanslar bellek sızıntılarına, hatalara veya kilitlenmelere neden olur.
  • Durum: İki farklı nesne örneği oldukları için eski Activity örneğindeki durum yeni Activity örneğinde mevcut değildir. Uygulamayı ve kullanıcı 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 etkinleştirmenin devre dışı bırakılması potansiyel bir optimizasyondur. Uygulamanızın, yeni yapılandırmaya tepki olarak doğru şekilde güncellenmesini gerektirir.

İyi bir kullanıcı deneyimi sunmak 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ç kiti ne olursa olsun yapılandırma değişikliklerinin nadiren meydana geldiğini veya hiçbir zaman gerçekleşmediğini varsaymayın. Kullanıcı, yapılandırma değişikliğine neden olduğunda uygulamaların güncellenmesini ve yeni yapılandırmayla düzgün bir şekilde çalışmaya devam etmesini bekler.
  • Durumu koru: Activity yeniden oluşturma gerçekleştiğinde kullanıcının durumunu kaybetmeyin. Durumu, Kullanıcı arayüzü durumlarını kaydetme konusunda açıklandığı gibi koruyun.
  • Hızlı bir çözüm olarak devre dışı bırakmaktan kaçının: Durum kaybını önlemek için kısayol olarak Activity yeniden oluşturmayı devre dışı bırakmayın. Etkinlik yeniden oluşturma işleminin devre dışı bırakılması, değişikliği ele alma sözünü yerine getirmenizi gerektirir. Ayrıca diğer yapılandırma değişikliklerinden kaynaklanan Activity yeniden oluşturma, işleme ölmesi veya uygulamayı kapatma nedeniyle durumu yine de kaybedebilirsiniz. Activity yeniden oluşturmayı tamamen devre dışı bırakmak mümkün değildir. Durumu, Kullanıcı arayüzü durumlarını kaydetme konusunda açıklandığı gibi koruyun.
  • Yapılandırma değişikliklerinden kaçının: Yapılandırma değişikliklerinden ve Activity yeniden oluşturma işleminden kaçınmak için yön, en boy oranı veya yeniden boyutlandırmayla ilgili kısıtlamalar uygulamayın. Bu durum, uygulamanızı tercih ettikleri şekilde kullanmak isteyen kullanıcıları olumsuz etkiler.

Boyut tabanlı yapılandırma değişikliklerini işleme

Boyuta dayalı yapılandırma değişiklikleri her an gerçekleşebilir ve uygulamanız kullanıcıların çoklu pencere moduna girebileceği büyük ekranlı bir cihazda çalıştığında gerçekleşir. Uygulamanızın bu ortamda iyi çalışmasını bekliyorlar.

İki genel boyut değişikliği türü vardır: önemli ve önemsiz. Önemli boyut değişikliği; genişlik, yükseklik veya en küçük genişlik gibi ekran boyutundaki farklılıklardan dolayı yeni yapılandırmaya farklı bir alternatif kaynak grubunun uygulanmasıdır. Bu kaynaklar, uygulamanın kendisini tanımladığı ve herhangi bir kitaplığındaki kaynakları içerir.

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() çağrısı alır. Eklenen tüm görünümler View.onConfigurationChanged() numarasına bir çağrı alır.

Manifest dosyanızda android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout" bulunuyorsa 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 boyuta dayalı yapılandırma değişiklikleri için önemli ölçüde değişiklik olursa gerçekleşir. Sistem, yetersiz boyut nedeniyle bir Activity öğesini yeniden oluşturmazsa sistem bunun yerine Activity.onConfigurationChanged() ve View.onConfigurationChanged() değerlerini çağırabilir.

Activity yeniden oluşturulmadığında Activity ve View geri çağırmalarıyla ilgili dikkat edilmesi 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 (API düzeyi 32) ve Android 13'ün erken sürümlerinde (API düzeyi 33) bazı durumlarda View.onConfigurationChanged() çağrılmayabileceği bilinen bir sorun vardır. Daha fazla bilgi için bu herkese açık soruna göz atın. O zamandan beri bu sorun sonraki Android 13 sürümlerinde ve Android 14'te giderilmiştir.

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