Saklanacak kaynakları özelleştirin

Uygulama optimizasyonunu etkinleştirdiğinizde, optimize edicinin varsayılan davranışı R8'in farklı sürümlerinde farklıdır.

  • AGP 9.3 ve sonraki sürümlerde kullanılabilen güncellenmiş DSL ile, optimizasyon etkinleştirildiğinde kaynak küçültme varsayılan olarak etkindir. Kod ve kaynak optimizasyonu gerektiren eski DSL'nin hâlâ desteklendiğini unutmayın.
  • AGP 9.3'ten önceki sürümlerde isShrinkResources = true ayarı, optimize ediciye kullanılmayan kaynakları kaldırması talimatını verir. Bu da uygulamanızın boyutunu küçültmeye yardımcı olur. Kaynak küçültme yalnızca kod küçültmeyle birlikte çalışır. Bu nedenle, kaynakları optimize ediyorsanız isMinifyEnabled = true ayarını da yapın.

AGP 9.3+ (Kotlin)

buildTypes {
    release {
        optimization {
            enable = true // Enables code and resource optimizations.
        }
    }
}

AGP 9.3+ (Groovy)

buildTypes {
    release {
        optimization {
            enable = true // Enables code and resource optimizations.
        }
    }
}

Eski DSL (Kotlin)

buildTypes {
    release {
        isMinifyEnabled = true
        isShrinkResources = true
        ...
    }
}

Eski DSL (Groovy)

buildTypes {
    release {
        minifyEnabled = true
        shrinkResources = true
        ...
    }
}

Belirli kaynakları saklamak veya silmek istiyorsanız proje kaynaklarınızda bir XML keep dosyası oluşturun (ör. res/raw/my.package.keep.xml). Keep dosyası aşağıdaki bileşenleri içerir:

  • <resources> etiketi: Tüm alt kaynak öğelerini ve keep/discard özelliklerini içerir.
  • tools:keep özelliği: Korunacak kaynakları tanımlayan, virgülle ayrılmış kaynak adı listesini kabul eder.
  • tools:discard özelliği: Atılacak kaynakları tanımlayan, virgülle ayrılmış kaynak adı listesini kabul eder.

Aynı klasördeki birden fazla kaynağa referans vermek için joker karakter olarak yıldız işaretini kullanın. Örneğin:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"
    tools:discard="@layout/unused2" />

Hangi kaynakların atılacağını belirtmek, bunları silmek yerine gereksiz görünebilir ancak derleme varyantlarını kullanırken kaynakları atmak faydalı olabilir.

Belirli derleme çeşitlerini hedefleme

Kaynakları yalnızca bazı derleme değişkenlerinde kaldırmak için tüm kaynaklarınızı ortak proje dizinine yerleştirin, ardından değişkenin kaynak dizininde her derleme değişkeni için farklı bir my.package.build.variant.keep.xml dosyası oluşturun. Keep dosyasında, belirli bir kaynak kodda kullanılıyor gibi göründüğünde (bu nedenle küçültücü tarafından kaldırılmaz) ancak aslında belirli bir derleme değişkeni için kullanılmayacağını bildiğinizde kaldırılacak kaynakları manuel olarak belirtin.

Kullanılmayan alternatif kaynakları kaldırma

Optimizasyon aracı yalnızca uygulama kodunuz tarafından referans verilmeyen kaynakları kaldırır. Bu nedenle, farklı cihaz yapılandırmaları için alternatif kaynakları kaldırmaz.

Uygulamanızın ihtiyaç duymadığı alternatif kaynak dosyalarını kaldırmak için uygulamanızın modül build.gradle dosyasında Android Gradle resConfigs özelliğini kullanın.

Örneğin, dil kaynakları (Google Play Hizmetleri gibi) içeren bir kitaplık kullanıyorsanız uygulamanızın geri kalanı aynı dillere çevrilmiş olsun veya olmasın, bu kitaplıklardaki mesajlar için çevrilmiş tüm dil dizelerini içerir. Uygulamanızın resmi olarak desteklediği dilleri korumak için bu dilleri resConfigs özelliğiyle belirtin. Belirtilmeyen dillerdeki kaynaklar kaldırılır.

Aşağıdaki snippet'lerde, dil kaynaklarınızı yalnızca İngilizce ve Fransızca ile nasıl sınırlayacağınız gösterilmektedir:

android {
    defaultConfig {
        ...
        resourceConfigurations.addAll(listOf("en", "fr"))
    }
}

veya

android {
    defaultConfig {
        ...
        resConfigs "en", "fr"
    }
}

Android App Bundle (AAB) biçimini kullanarak bir uygulama yayınladığınızda, kullanıcı uygulamayı yüklediğinde varsayılan olarak yalnızca kullanıcının cihazında yapılandırılan diller indirilir. Benzer şekilde, yalnızca cihazın ekran yoğunluğuyla eşleşen kaynaklar ve cihazın ABI'siyle eşleşen yerel kitaplıklar indirmeye dahil edilir. Daha fazla bilgi için Yapılandırma APK'larının türlerini yeniden etkinleştirme veya devre dışı bırakma başlıklı makaleyi inceleyin.

APK'larla yayınlanan eski uygulamalar (Ağustos 2021'den önce oluşturulanlar) için farklı cihaz yapılandırmalarını hedefleyen birden fazla APK oluşturarak ekran yoğunluğu veya ABI kaynaklarını APK'nıza dahil edilecek şekilde özelleştirebilirsiniz.

Kaynakları birleştirirken çakışmaları önleme

Android Gradle eklentisi (AGP), varsayılan olarak aynı ada sahip kaynakları (ör. farklı kaynak klasörlerindeki aynı ada sahip çizilebilir öğeler) birleştirir. Bu davranış, shrinkResources özelliği tarafından kontrol edilmez ve devre dışı bırakılamaz. Bunun nedeni, kodunuzun referans verdiği birden fazla kaynak aynı ada sahip olduğunda hataları önlemek için bu davranışın gerekli olmasıdır.

Kaynak birleştirme yalnızca iki veya daha fazla dosya aynı kaynak adını, türünü ve niteleyiciyi paylaştığında gerçekleşir. AGP, yinelenenler arasında en iyi seçenek olduğunu belirlediği dosyayı (aşağıda açıklanan öncelik sırasına göre) seçer ve son derleme yapısında dağıtılmak üzere yalnızca bu kaynağı AAPT'ye iletir.

AGP, aşağıdaki konumlarda yinelenen kaynakları arar:

  • Ana kaynak grubuyla ilişkili ana kaynaklar genellikle şu konumda bulunur: src/main/res/
  • Derleme türü ve derleme çeşitlerine göre varyant yer paylaşımları
  • Kitaplık projesi bağımlılıkları

AGP, yinelenen kaynakları aşağıdaki basamaklı öncelik sırasına göre birleştirir:

Bağımlılıklar → Ana → Derleme aroması → Derleme türü

Örneğin, hem ana kaynaklarınızda hem de bir derleme türünde aynı kaynak görünüyorsa Gradle, derleme türündeki kaynağı seçer.

Aynı kaynak kümesinde aynı kaynaklar görünürse Gradle bunları birleştiremez ve kaynak birleştirme hatası verir. Bu durum, modülünüzün build.gradle dosyasının sourceSet özelliğinde birden fazla kaynak kümesi tanımlarsanız (ör. hem src/main/res/ hem de src/main/res2/ aynı kaynakları içeriyorsa) ortaya çıkabilir.

Kullanılmayan kaynakları kaldırma ile ilgili sorunları giderme

Kaynakları küçülttüğünüzde Build (Derleme) penceresinde uygulamadan kaldırılan kaynakların özeti gösterilir. (Gradle'dan ayrıntılı metin çıkışı görüntülemek için pencerenin sol tarafındaki Toggle view'u (Görünümü değiştir) tıklayın.) Örneğin:

:android:shrinkDebugResources
Removed unused resources: Resource data reduced from 2570KB to 1711KB: Removed 33%
:android:validateDebugSigning

Gradle, resources.txt in <module-name>/build/outputs/mapping/release/ (ProGuard çıkış dosyalarıyla aynı klasör) adlı bir teşhis dosyası da oluşturur. Dosyada, hangi kaynakların diğer kaynaklara referans verdiği ve hangi kaynakların kullanıldığı veya kaldırıldığı gibi ayrıntılar yer alır.

Örneğin, @drawable/ic_plus_anim_016 öğesinin neden hâlâ uygulamanızda olduğunu öğrenmek için resources.txt dosyasını açıp bu dosya adını arayın. Başka bir kaynakta referans verildiğini görebilirsiniz:

16:25:48.005 [QUIET] [system.out] @drawable/add_schedule_fab_icon_anim : reachable=true
16:25:48.009 [QUIET] [system.out] @drawable/ic_plus_anim_016

Artık @drawable/add_schedule_fab_icon_anim kaynağına neden ulaşılabildiğini bilmeniz gerekiyor. Yukarı doğru arama yaptığınızda, kaynağın resources.txt bölümündeki Temel ulaşılabilir kaynaklar: başlığı altında listelendiğini görürsünüz.

Bu, add_schedule_fab_icon_anim için bir kod referansı olduğu anlamına gelir. Yani R.drawable kimliği, erişilebilir kodda bulunmuştur.

Katı kontrol kullanmıyorsanız dinamik olarak yüklenen kaynakların kaynak adlarını oluşturmak için kullanılabilecek gibi görünen dize sabitleri varsa kaynak kimlikleri erişilebilir olarak işaretlenebilir. Bu durumda, derleme çıktısında kaynak adını ararsanız şu gibi bir mesaj görebilirsiniz:

10:32:50.590 [QUIET] [system.out] Marking drawable:ic_plus_anim_016:2130837506
    used because its format-string matches string pool constant ic_plus_anim_%1$d.

Bu dizelerden birini görüyorsanız ve dizenin, söz konusu kaynağı dinamik olarak yüklemek için kullanılmadığından eminseniz derleme sistemine kaynağı kaldırması talimatını vermek için keep dosyanızda tools:discard özelliğini kullanın.