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ğıda belirtilmiştir ancak bunlarla sınırlı değildir:

  • Uygulama görüntüleme boyutu
  • Ekran yönü
  • Yazı tipi boyutu ve ağırlığı
  • Yerel ayar
  • Koyu mod ve 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ğerleri 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.

Etkinlik rekreasyon

Bir yapılandırma değişikliği gerçekleştiğinde sistem bir Activity öğesini 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şturduğu 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 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 TextView düşünün. Görünüm oluşturulduğunda, geçerli 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.

Yeniden oluşturma, Activity 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 değildir. Bu nedenle, bu öğeye veya içerdiği nesnelere ilişkin geri kalan referanslar eskidir. Hatalara, bellek sızıntılarına ve kilitlenmelere neden olabilirler.

Kullanıcıların beklentileri

Bir uygulamanın kullanıcısı durumun korunmasını bekler. Bir kullanıcı bir form doldururken bilgilere referans vermek için başka bir uygulamayı çoklu pencere modunda açarsa temiz bir forma veya uygulamada tamamen başka bir yere 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 pencereyken uygulamayı yeniden boyutlandırma
  • Birden fazla ekrana sahip 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
  • Yuvaya bağlanma 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 tamamlamayı ele almak için yerel kalıcılık. Kalıcı yerel depolama alanına veritabanları veya DataStore dahildir.
  • Kullanıcı uygulamayı aktif olarak kullanırken bellekteki kullanıcı arayüzü ile ilgili durumu işlemek için ViewModel örnekleri gibi tsaklanan nesneler.
  • Sistem tarafından başlatılan işlem ölümünü işlemek ve kullanıcı girişine veya gezinmeye bağlı olarak geçici durumu korumak için kayıtlı örnek durumu.

Bu API'lerin her birine ilişkin API'ler hakkında ayrıntılı bilgi edinmek ve her birinin uygun olup olmadığını öğrenmek için Kullanıcı arayüzü durumlarını kaydetme bölümüne bakın.

Aktivite ve dinlenmeyi 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 kendisinin 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şturmayı devre dışı bırakmak üzere yapılandırma türünü AndroidManifest.xml dosyanızın <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şturma özelliğini 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, Activity.onConfigurationChanged() çağrısı alır. Ekli görünümlerde View.onConfigurationChanged() çağrısı da yapılır. android:configChanges öğesine 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 kaynaklar 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() öğesini 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ü boyunca durumu 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.
  • İşlem ölümü: 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 bileşimi yerel olarak kullanılabilir. Kod değiştiğinde, LocalConfiguration.current tarihinden itibaren okunan composable işlevler yeniden derlenir. Beste yerellerinin işleyiş şekli hakkında bilgi edinmek için CompositionLocal ile yerel olarak kapsama alınmış veriler bölümüne bakın.

Örnek

Aşağıdaki örnekte bir composable, belirli bir biçime sahip tarihi gösterir. composable, LocalConfiguration.current ile ConfigurationCompat.getLocales() yöntemini çağırarak 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 yeniden oluşturulmasını önlemek için Oluşturma kodunu barındıran Activity, yerel yapılandırma 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 önlemenin bir yolu yoktur.
  • Activity yeniden oluşturma: Yapılandırma değişiklikleri, varsayılan olarak Activity yeniden oluşturma ile sonuçlanır. Bu, yeni yapılandırmanın uygulama durumunu yeniden başlatmak için kullanılan 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.
  • State: Eski Activity örneğindeki durum, iki farklı nesne örneği oldukları için yeni Activity örneğinde mevcut değildir. 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 tür yapılandırma değişikliği için etkinliği yeniden oluşturma özelliğinin devre dışı bırakılması olası bir optimizasyondur. Uygulamanızın yeni yapılandırmaya tepki olarak doğru şekilde güncellenmesi gerekir.

İyi bir kullanıcı deneyimi sunmak için aşağıdaki en iyi uygulamaları göz önünde bulundurun:

  • Sık sık yapılandırma değişikliklerine hazır olun: API düzeyi, form faktörü veya kullanıcı arayüzü araç kiti ne olursa olsun yapılandırma değişikliklerinin nadiren olacağını veya hiçbir zaman gerçekleşmeyeceğ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 bölümünde 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 özelliğini devre dışı bırakmak, değişikliği işleme sözünü yerine getirmenizi gerektirir. Ancak diğer yapılandırma değişikliklerinden 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 bölümünde 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ırılabilirlik 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 her an gerçekleşebilir ve büyük ekranlı bir cihazda, 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ı beklerler.

İki tür boyut değişikliği vardır: önemli ve önemsiz. Önemli boyut değişikliği; genişlik, yükseklik veya en küçük genişlik gibi ekran boyutu farkı nedeniyle yeni yapılandırmaya farklı bir alternatif kaynak grubunun uygulanmasıdır. Bu kaynaklar, uygulamanın kendisini tanımlayanları 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() numarasına bir çağrı alır. Ekli görüntülemeler, View.onConfigurationChanged() numarasına sesli arama yapar.

Manifest dosyanızda android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout" bulunuyorsa Activity yeniden oluşturma, boyuta dayalı yapılandırma değişiklikleri için 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 bir değişiklik olması durumunda gerçekleşir. Sistem, yetersiz boyut nedeniyle bir Activity öğesini yeniden oluşturmazsa 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 sayıya göz atın. Bu sorun, sonraki Android 13 ve Android 14 sürümlerinde düzeltilmiştir.

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