Uygulamanızı küçültme, gizleme ve optimize etme

Uygulamanızı olabildiğince küçük ve hızlı hale getirmek için sürüm derlemeniz için isMinifyEnabled = true kullanın.

Bu, küçültmeyi sağlayarak kullanılmayan kodları ve kaynakları kaldırır; Kod karartma: Uygulamanızdaki sınıfların ve üyelerin adlarını kısaltır. ve optimizasyon yöntemi, tıklama başına maliyeti daha da azaltmak için daha agresif stratejiler uygular uygulamanızın boyutunu ve performansını artırın. Bu sayfada, R8'in derleme zamanında istenen görevleri nasıl gerçekleştireceğinizi ve gerekir.

Projenizi Android Gradle eklentisi 3.4.0 veya sonraki sürümler, Eklenti, derleme zamanı kod optimizasyonu yapmak için artık ProGuard'ı kullanmamaktadır. Bunun yerine eklenti aşağıdaki işlemleri yapmak için R8 derleyici ile çalışır: derleme zamanı görevleri:

  • Kod küçültme (veya ağaç sallama): Kullanılmayan kodları tespit edip güvenli bir şekilde ortadan kaldırma Uygulamanızdan ve kitaplığından sınıflar, alanlar, yöntemler ve özellikler bağımlılıkları (bu da bağımlılıkları çözmek için değerli bir araç haline getirir.) 64.000 referans sınırı). Örneğin, bir kitaplık bağımlılığının yalnızca birkaç API'sini; daraltma işlemi ile kitaplık kodu tanımlanabilir kullanmadığını belirtmeli ve yalnızca bu kodu kaldırmalısınız. Alıcı: daha fazla bilgi için kodunuzu küçültme ile ilgili bölüme gidin.
  • Kaynak daraltma: Kullanılmayan kaynakları paketlenmiş uygulamanızdan kaldırır, uygulamanızın kitaplık bağımlılıklarındaki kullanılmayan kaynaklar dahil edilir. Şurada çalışır: Örneğin, kullanılmayan kod kaldırıldıktan sonra kod küçültme başvurulan kaynaklar da güvenli bir şekilde kaldırılabilir. Öğrenmek için daha fazla bilgi edinmek için kaynaklarınızı küçültün.
  • Optimizasyon: Çalışma zamanını iyileştirmek için kodunuzu inceler ve yeniden yazar performansını artırır ve uygulamanızın DEX dosyalarının boyutunu daha da küçültür. Bu kodun çalışma zamanı performansını %30'a varan oranlarda artırarak başlatma ve kare zamanlaması. Örneğin, R8, else {} belirli bir if/else ifadesi asla alınmazsa, R8, else {} dalı. Daha fazla bilgi edinmek için kod optimizasyonu.
  • Karartma (veya tanımlayıcı küçültme): Sınıfların adını kısaltır Bu da DEX dosya boyutlarının küçültülmesini sağlar. Daha fazla bilgi edinmek için şu adresi ziyaret edin: kodunuzu karartma ile ilgili bölüme bakın.

R8, uygulamanızın sürüm sürümünü oluştururken iyi performans sergileyecek şekilde yapılandırılabilir. sizin için yukarıda açıklanan derleme süresi görevlerini gözden geçirin. Ayrıca, belirli iletişim birimlerini görevleri yapabilir veya ProGuard kural dosyalarıyla R8'in davranışını özelleştirebilirsiniz. Aslında R8, tüm mevcut ProGuard kural dosyalarınızla çalışır, bu nedenle Android Gradle eklentisini R8 kullanacak şekilde güncellemek için kontrol edebilirsiniz.

Daraltmayı, kod karartmayı ve optimizasyonu etkinleştirme

Android Studio 3.4 veya Android Gradle eklentisi 3.4.0 ve sonraki sürümleri kullandığınızda R8 projenizin Java bayt kodunu DEX'e dönüştüren varsayılan derleyici Android platformunda çalıştırılan bir biçim. Ancak yeni bir proje oluşturduğunuzda küçültme, kod karartma ve kod optimizasyonu gibi pek çok işlevin varsayılan olarak etkindir. Bunun nedeni, bu derleme zamanı optimizasyonlarının ve doğru şekilde ayarlamazsanız hatalara neden olabilir. hangi kodun tutulacağını özelleştirme.

Bu nedenle, nihai sürümü oluştururken bu derleme zamanı görevlerini etkinleştirmek en iyisidir test edin. Daraltmayı, kod karartmayı ve ve optimizasyon gerçekleştiriyorsanız proje düzeyinde derleme komut dosyanıza aşağıdakileri ekleyin.

Kotlin

android {
    buildTypes {
        getByName("release") {
            // Enables code shrinking, obfuscation, and optimization for only
            // your project's release build type. Make sure to use a build
            // variant with `isDebuggable=false`.
            isMinifyEnabled = true

            // Enables resource shrinking, which is performed by the
            // Android Gradle plugin.
            isShrinkResources = true

            proguardFiles(
                // Includes the default ProGuard rules files that are packaged with
                // the Android Gradle plugin. To learn more, go to the section about
                // R8 configuration files.
                getDefaultProguardFile("proguard-android-optimize.txt"),

                // Includes a local, custom Proguard rules file
                "proguard-rules.pro"
            )
        }
    }
    ...
}

Eski

android {
    buildTypes {
        release {
            // Enables code shrinking, obfuscation, and optimization for only
            // your project's release build type. Make sure to use a build
            // variant with `debuggable false`.
            minifyEnabled true

            // Enables resource shrinking, which is performed by the
            // Android Gradle plugin.
            shrinkResources true

            // Includes the default ProGuard rules files that are packaged with
            // the Android Gradle plugin. To learn more, go to the section about
            // R8 configuration files.
            proguardFiles getDefaultProguardFile(
                    'proguard-android-optimize.txt'),
                    'proguard-rules.pro'
        }
    }
    ...
}

R8 yapılandırma dosyaları

R8, varsayılan davranışını değiştirmek ve daha iyi hale getirmek için ProGuard kural dosyalarını kullanır Uygulamanızın yapısını (ör. giriş noktaları olarak işlev gören sınıflar) anlama içine yerleştirmeniz gerekir. Bu kural dosyalarından bazılarını değiştirebilirsiniz, ancak kurallar, AAPT2 gibi derleme zamanı araçları tarafından otomatik olarak oluşturulabilir veya uygulamanızın kitaplık bağımlılıklarından devralınır. Aşağıdaki tabloda ve R8'in kullandığı ProGuard kural dosyalarının kaynaklarını görebilirsiniz.

Kaynak Konum Açıklama
Android Studio <module-dir>/proguard-rules.pro Android Studio'yu kullanarak yeni bir modül oluşturduğunuzda, IDE, yeni bir proguard-rules.pro dosyasını yükleyebilirsiniz.

Varsayılan olarak bu dosya herhangi bir kural uygulamaz. Bu nedenle, Buradaki ProGuard kuralları, özel kuralları koru.

Android Gradle eklentisi Derleme sırasında Android Gradle eklentisi tarafından oluşturuldu. Android Gradle eklentisi proguard-android-optimize.txt (bunun gibi kurallar), Pek çok Android projesi için kullanışlıdır ve @Keep* ek açıklamaları inceleyin.

Varsayılan olarak, Android Studio'yu kullanarak yeni bir modül oluştururken modül düzeyindeki derleme komut dosyası, sürüm derlemenize bu kural dosyasını içerir sizin için.

Not: Android Gradle eklentisi önceden tanımlanmış ek ProGuard yardımcı olabilir, ancak yine de proguard-android-optimize.txt.

Kitaplık bağımlılıkları

Bir AAR kitaplığında:
proguard.txt

Bir JAR kitaplığında:
META-INF/proguard/<ProGuard-rules-file>

Bu konumlara ek olarak Android Gradle eklentisi 3.6 veya sonraki sürümleri de hedeflenen daraltma kurallarını destekler.

Bir AAR veya JAR kitaplığı kendi kural dosyasıyla yayınlanırsa ve bu kitaplığı, derleme süresinde bağımlılık olarak dahil eder, R8 otomatik olarak uygulamanızı derlerken bu kuralları uygular.

Geleneksel ProGuard kurallarına ek olarak, Android Gradle eklentisi 3.6 veya sonraki sürümler de şu sürümleri destekler: hedeflenen daraltma kurallarını kullanın. Bunlar, kurallardır belirli büzücüleri (R8 veya ProGuard) hedefleyen ve aynı zamanda küçülebilir.

Kitaplıklarla paketlenmiş kural dosyalarını kullanmak, belirli kitaplığın, yani kitaplığın düzgün çalışması için geliştirici, sorun giderme adımlarını sizin için uyguladı.

Ancak kurallar eklemeye dayalı olduğundan, kitaplık bağımlılığının içerdiği belirli kurallar kaldırılamaz ve Uygulamanızın diğer bölümlerinin derlenmesini etkileyebilir. Örneğin, kitaplığı, kod optimizasyonlarını devre dışı bırakan bir kural içerir. Bu kural, en iyi uygulamaları paylaşacağız.

Android Öğe Paketi Aracı 2 (AAPT2) Projenizi minifyEnabled true ile oluşturduktan sonra: <module-dir>/build/intermediates/aapt_proguard_file/.../aapt_rules.txt AAPT2, uygulamanızın manifest'i, düzenleri ve diğer uygulama kaynaklarını bulun. Örneğin, AAPT2 uygulamanızın manifest dosyasına bir etkinlik olarak kaydettiğiniz her Etkinlik için giriş noktası.
Özel yapılandırma dosyaları Varsayılan olarak, Android Studio'yu kullanarak yeni bir modül oluşturduğunuzda IDE Kendinizinkini eklemeniz için <module-dir>/proguard-rules.pro oluşturur kurallar. Ek yapılandırmalar ekleyebilir, ve R8 bunları derleme sırasında uygular.

minifyEnabled özelliğini true olarak ayarladığınızda R8, yukarıda listelenen kullanılabilir kaynaklar. Bu aşamayı ne zaman R8 ile sorun giderin çünkü diğer derleme süresi bağımlılıkları, ve kütüphane bağımlılıkları gibi işletim sistemi, kullandığınız R8 davranışında da emin değilim.

Modelinizi oluştururken R8'in uyguladığı tüm kuralları içeren eksiksiz bir rapor oluşturmak için projesini değiştirmek istiyorsanız modülünüzün proguard-rules.pro dosyasına aşağıdakileri ekleyin:

// You can specify any path and filename.
-printconfiguration ~/tmp/full-r8-config.txt

Hedefli daraltma kuralları

Android Gradle eklentisi 3.6 veya sonraki sürümler kitaplıkları destekler kuralların farklılığını (R8 veya ProGuard) ve belirli büzücü versiyonları olabilir. Bu kitaplık geliştiricilerinin, kurallarını projelerde en iyi şekilde çalışacak şekilde uyarlamalarına olanak tanır yeni daraltıcı sürümleri kullanan, ancak mevcut kuralların uyumlu olmaya devam etmesine eski daraltıcı sürümlere sahip projelerde kullanılır.

Hedeflenen daraltma kurallarını belirtmek için kitaplık geliştiricilerinin bunları dahil etmesi gerekir aşağıda açıklandığı gibi bir AAR veya JAR kitaplığındaki belirli konumlarda

In an AAR library:
    proguard.txt (legacy location)
    classes.jar
    └── META-INF
        └── com.android.tools (targeted shrink rules location)
            ├── r8-from-<X>-upto-<Y>/<R8-rules-file>
            └── proguard-from-<X>-upto-<Y>/<ProGuard-rules-file>

In a JAR library:
    META-INF
    ├── proguard/<ProGuard-rules-file> (legacy location)
    └── com.android.tools (targeted shrink rules location)
        ├── r8-from-<X>-upto-<Y>/<R8-rules-file>
        └── proguard-from-<X>-upto-<Y>/<ProGuard-rules-file>

Bu, hedeflenen daraltma kurallarının META-INF/com.android.tools içinde depolandığı anlamına gelir. JAR dizininde veya META-INF/com.android.tools dizininde AAR'nin classes.jar.

Bu dizin altında, belirtmek için r8-from-<X>-upto-<Y> veya proguard-from-<X>-upto-<Y> , dizinlerdeki kuralların yazıldığı daraltıcı sürümleridir. -from-<X> ve -upto-<Y> bölümlerinin isteğe bağlı olduğunu unutmayın. <Y> sürümü hariç ve sürüm aralıkları sürekli olmalıdır.

Örneğin r8-upto-8.0.0, r8-from-8.0.0-upto-8.2.0 ve r8-from-8.2.0 geçerli bir hedeflenen küçültme kuralları grubu oluşturmalıdır. Altındaki kurallar r8-from-8.0.0-upto-8.2.0 dizini sürüm 8.0.0 ile R8 tarafından kullanılır ancak 8.2.0 sürümü dahil değildir.

Bu bilgiler ışığında, Android Gradle eklentisi 3.6 veya sonraki bir sürüm kurallarından birini seçin. Bir kitaplık hedeflendiğini belirtmiyorsa küçültme kurallarından yararlanırsanız Android Gradle eklentisi, kodu eski (AAR için proguard.txt veya JAR için META-INF/proguard/<ProGuard-rules-file>).

Kitaplık geliştiricileri, hedeflenen daraltma kurallarını veya eski politikaları eklemeyi seçebilir Kitaplıklarındaki veya her iki türdeki ProGuard kurallarını da korumak istiyorlarsa 3.6'dan eski Android Gradle eklentisi veya diğer araçlarla uyumluluk.

Ek yapılandırmaları dahil et

Android Studio'yu kullanarak yeni bir proje veya modül oluşturduğunuzda, IDE (Entegre Geliştirme Ortamı) bir <module-dir>/proguard-rules.pro dosyası kullanarak kendi kurallarınızı dahil edebilirsiniz. Siz diğer dosyalardan ek kurallar da dahil etmek için, onları Modülünüzün derleme komut dosyasında proguardFiles özelliğini ekleyin.

Örneğin, her bir derleme varyantına özel kurallar eklemek için İlgili productFlavor bloğunda başka bir proguardFiles özelliği. İlgili içeriği oluşturmak için kullanılan aşağıdaki Gradle dosyası flavor2 ürün aromasına flavor2-rules.pro ekler. Şimdi, flavor2 üç ProGuard kuralının tümünü kullanır çünkü release engellemeleri de uygulanır.

Buna ek olarak, testProguardFiles özelliğini ekleyebilirsiniz. Bu özellik, Yalnızca test APK'sında yer alan ProGuard dosyalarının listesi:

Kotlin

android {
    ...
    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                // List additional ProGuard rules for the given build type here. By default,
                // Android Studio creates and includes an empty rules file for you (located
                // at the root directory of each module).
                "proguard-rules.pro"
            )
            testProguardFiles(
                // The proguard files listed here are included in the
                // test APK only.
                "test-proguard-rules.pro"
            )
        }
    }
    flavorDimensions.add("version")
    productFlavors {
        create("flavor1") {
            ...
        }
        create("flavor2") {
            proguardFile("flavor2-rules.pro")
        }
    }
}

Eski

android {
    ...
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles
                getDefaultProguardFile('proguard-android-optimize.txt'),
                // List additional ProGuard rules for the given build type here. By default,
                // Android Studio creates and includes an empty rules file for you (located
                // at the root directory of each module).
                'proguard-rules.pro'
            testProguardFiles
                // The proguard files listed here are included in the
                // test APK only.
                'test-proguard-rules.pro'
        }
    }
    flavorDimensions "version"
    productFlavors {
        flavor1 {
            ...
        }
        flavor2 {
            proguardFile 'flavor2-rules.pro'
        }
    }
}

Kodunuzu küçültün

minifyEnabled özelliğini ayarladığınızda R8 ile kod daraltma varsayılan olarak etkinleştirilir özelliğini true olarak ayarlayın.

Kod küçülme (ağaç sallama olarak da bilinir), kodları kaldırma işlemidir. R8'in çalışma zamanında gerekli olmadığını belirlediğinden emin olun. Bu süreç önemli ölçüde Örneğin, uygulamanız pek çok kitaplık bağımlılığı içeriyorsa ancak yalnızca küçük bir kısmını kullanıyor.

R8, uygulamanızın kodunu küçültmek için öncelikle uygulamanızın kod, birleştirilmiş yapılandırma dosyaları grubuna dayanır. Bu giriş noktaları, Android platformunun şu web sitelerini açmak için kullanabileceği tüm sınıfları içerir: uygulamanızın Etkinlikleri veya hizmetleri. R8 her giriş noktasından başlayarak tüm yöntemlerin, üye değişkenlerinin ve diğer metriklerin bir grafiğini oluşturmak için sınıfları belirleyin. Bağlı olmayan kod Söz konusu grafik ulaşılamaz olarak kabul edilir ve uygulamadan kaldırılabilir.

Şekil 1'de çalışma zamanı kitaplığı bağımlılığı olan bir uygulama gösterilmektedir. R8, foo(), faz() ve bar() yöntemlerinin MainActivity.class giriş noktasından erişilebilir. Ancak, OkayApi.class veya baz() yöntemi, çalışma zamanında uygulamanız tarafından hiçbir zaman kullanılmaz ve R8, uygulamanızı küçültürken bu kodu kaldırır.

Şekil 1. R8, derleme sırasında bir projenize erişilemeyen kodu belirlemek için bu birleşik kuralları temel alan grafiktir.

R8, giriş noktalarını projenin -keep kuralları aracılığıyla belirler R8 yapılandırma dosyaları. Yani, bu tür durumlarda uygulamanızı küçültürken silmemesi gereken sınıfları ve R8'in bu sınıfları uygulamanıza giriş noktaları olarak ekleyin. Android Gradle eklentisi ve AAPT2, çoğu uygulama için gereken saklama kurallarını otomatik olarak oluşturur. gibi farklı proje türlerini (ör. uygulamanızın etkinlikleri, görünümleri ve hizmetleri) Ancak, bu varsayılan davranışı ek saklama kurallarıyla özelleştirmeniz gerekiyorsa hangi kodun saklanacağını özelleştirme ile ilgili bölüme bakın.

Bunun yerine yalnızca uygulamanızın kaynaklarının boyutunu küçültmekle ilgileniyorsanız kaynaklarınızı küçültme ile ilgili bölüme geçin.

Bir kitaplık projesi küçültüldüyse bu kitaplığa bağlı bir uygulama daraltılmış kitaplık sınıflarını içerir. Aşağıdaki durumlarda kitaplık saklama kurallarını ayarlamanız gerekebilir: kitaplık APK'sında eksik sınıflar var. Bir web sitesi tasarlıyor ve AAR biçiminde bir kitaplık, kitaplığınızın kullandığı yerel JAR dosyaları değil küçültülmüştür.

Saklanacak kodu özelleştirin

Çoğu durumda, varsayılan ProGuard kuralları dosyası (proguard-android-optimize.txt) R8'in yalnızca kullanılmayan kodu kaldırması için yeterlidir. Ancak, bazı durumları R8'in doğru şekilde analiz etmesi zordur ve koda ihtiyacınız vardır. İçeriğin yanlışlıkla kaldırılabileceği durumlara dair bazı örnekler kodunuz:

  • Uygulamanız Java Yerel Arayüzü'nden (JNI) bir yöntem çağırdığında
  • Uygulamanız çalışma zamanında kod aradığında (ör. yansıma sırasında)

Uygulamanızı test etmek, uygunsuz bir şekilde kaldırma işleminden kaynaklanan hataları ortaya çıkarmalıdır ancak hangi kodun hangi uygulama veya öğe tarafından kaldırıldığını kaldırılan kod hakkında bir rapor oluşturma.

Hataları düzeltmek ve R8'i belirli kodu saklamaya zorlamak için bir -keep satırının değerini (ör. ProGuard kuralları) içerebilir. Örnek:

-keep public class MyClass

Alternatif olarak @Keep ek açıklaması iyi bir fırsattır. Sınıfa @Keep eklendiğinde tüm sınıf olduğu gibi kalır. Bir yönteme veya alana eklendiğinde yöntem/alan (ve adı) da korunur. üzerinde değişiklik yapabilirsiniz. Bu ek açıklama yalnızca "the" AndroidX Ek Açıklama Kitaplığı Android ile birlikte gelen ProGuard kuralları dosyasını da Şu bölümde açıklandığı gibi Gradle eklentisi: küçültmeyi etkinleştir.

-keep seçeneğini kullanırken dikkat etmeniz gereken birçok nokta vardır; şunun için: kurallarınızı özelleştirme hakkında daha fazla bilgi için ProGuard Kılavuzu. İlgili içeriği oluşturmak için kullanılan Sorun giderme bölümünde, kodunuz almaya başladığında karşılaşabileceğiniz diğer yaygın sorunlar soyutlanır.

Yerel kitaplıkları çıkar

Varsayılan olarak, uygulamanızın sürüm derlemelerindeki yerel kod kitaplıkları çıkarılır. Bu çıkarma işlemi, simge tablosunun kaldırılması ve hata ayıklama bilgilerinin uygulamanızın kullandığı yerel kitaplıklarda da yer alır. Yerel kodu çıkarma kitaplıklar önemli ölçüde boyut tasarrufu sağlar; Ancak değişiklikleri teşhis etmek nedeniyle Google Play Console'da kilitleniyor (örneğin, sınıf ve işlev adları).

Yerel kilitlenme desteği

Google Play Console, Android vitals. Birkaç kişilik adımlarında, uygulamanız için yerel hata ayıklama simgeleri dosyası oluşturup yükleyebilirsiniz. Bu dosya, simgeselleştirilmiş yerel kilitlenme yığın izlemelerini (sınıf ve işlev adları) eklemelerini öneririz. Bu adımlar, hem de projenizin derleme çıktısını değerlendireceksiniz.

Android Gradle eklentisi 4.1 veya sonraki sürümleri

Projeniz bir Android App Bundle derliyorsa şunu otomatik olarak ekleyebilirsiniz: yerel hata ayıklama simgeleri dosyası oluşturun. Bu dosyayı sürüm derlemelerine dahil etmek için uygulamanızın build.gradle.kts dosyasına göre:

android.buildTypes.release.ndk.debugSymbolLevel = { SYMBOL_TABLE | FULL }

Aşağıdakilerden hata ayıklama sembolü düzeyini seçin:

  • Play Console'un simgeselleştirilmiş yığın izlemelerinde işlev adlarını almak için SYMBOL_TABLE kullanın. Bu düzey mezar taşlarını destekler.
  • Play Console'da işlev adlarını, dosyaları ve satır numaralarını almak için FULL yığın izlemeleri temsil eder.
ziyaret edin.

Projeniz bir APK derliyorsa gösterilen build.gradle.kts derleme ayarını kullanın yerel hata ayıklama simgeleri dosyasını ayrı olarak oluşturun. Manuel olarak yerel hata ayıklama simgeleri dosyasını yükleme Google Play Console'a. Derleme sürecinin bir parçası olarak Android Gradle, eklentisi bu dosyayı aşağıdaki proje konumuna çıkarır:

app/build/outputs/native-debug-symbols/variant-name/native-debug-symbols.zip

Android Gradle eklentisi 4.0 veya önceki sürümler (ve diğer derleme sistemleri)

Android Gradle eklentisi, derleme işleminin bir parçası olarak sadeleştirilmiş kitaplıklar olduğunu unutmayın. Bu dizin yapısı şuna benzer:

app/build/intermediates/cmake/universal/release/obj/
├── armeabi-v7a/
│   ├── libgameengine.so
│   ├── libothercode.so
│   └── libvideocodec.so
├── arm64-v8a/
│   ├── libgameengine.so
│   ├── libothercode.so
│   └── libvideocodec.so
├── x86/
│   ├── libgameengine.so
│   ├── libothercode.so
│   └── libvideocodec.so
└── x86_64/
    ├── libgameengine.so
    ├── libothercode.so
    └── libvideocodec.so
  1. Bu dizinin içeriğini zip dosyası olarak kaydedin:

    cd app/build/intermediates/cmake/universal/release/obj
    zip -r symbols.zip .
    
  2. Manuel olarak symbols.zip dosyasını yükleyin Google Play Console'a.

ziyaret edin. .

Kaynaklarınızı küçültün

Kaynak daraltma yalnızca kod daraltma ile birlikte çalışır. kod daraltıcı, kullanılmayan tüm kodları kaldırır, kaynak daraltıcı hangi kaynaklar arasında yer alır. Bu durum özellikle YouTube'da kaynak içeren kitaplıklar: kütüphane kaynaklarına referansta bulunulmaz ve bu nedenle kaynak tarafından kaldırılabilir. yardımcı olur.

Kaynak daraltmayı etkinleştirmek için shrinkResources özelliğini ayarlayın. derleme komut dosyanızdaki true öğesine ( Kod küçültme için minifyEnabled). Örnek:

Kotlin

android {
    ...
    buildTypes {
        getByName("release") {
            isShrinkResources = true
            isMinifyEnabled = true
            proguardFiles(
                getDefaultProguardFile("proguard-android.txt"),
                "proguard-rules.pro"
            )
        }
    }
}

Eski

android {
    ...
    buildTypes {
        release {
            shrinkResources true
            minifyEnabled true
            proguardFiles
                getDefaultProguardFile('proguard-android.txt'),
                'proguard-rules.pro'
        }
    }
}

Henüz minifyEnabled için kullanarak uygulamanızı oluşturmadıysanız daha sonra shrinkResources'i etkinleştirmeden önce bu işlemi deneyin. çünkü proguard-rules.pro dosyanızı şu şekilde düzenlemeniz gerekebilir: dinamik olarak oluşturulan veya çağrılan sınıfları ya da yöntemleri kaynakları çıkarmaya başlayabilirsiniz.

Saklanacak kaynakları özelleştirin

Saklamak veya silmek istediğiniz belirli kaynaklar varsa XML oluşturun. projenizde <resources> etiketi kullanarak her bir dosyayı tools:keep özelliğinde tutulacak bir kaynak ve her bir tools:discard özelliğinde silin. Her iki özellik de kaynak adlarının virgülle ayrılmış listesi. Yıldız karakterini joker karakter.

Örnek:

<?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" />

Bu dosyayı proje kaynaklarınıza kaydedin. Örneğin: res/raw/my.package.keep.xml Derleme bu dosyayı uygulamasını indirin.

Not: keep dosyası için benzersiz bir ad kullandığınızdan emin olun. Zaman farklı kitaplıklar birbirine bağlanıyor, saklama kuralları çakışır aksi takdirde, yoksayılan kurallarla ilgili olası sorunlara neden olabilir veya kaynaklar.

Hangi kaynakların silineceğini belirtmek, silebilirsiniz. Ancak bu işlem, derleme varyantları kullanırken faydalı olabilir. Örneğin, tüm kaynaklarınızı, ortak proje dizinine yerleştirebilirsiniz. daha sonra her biri için farklı bir my.package.build.variant.keep.xml dosyası oluşturun belirli bir kaynağın kodda kullanıldığını bildiğiniz durumlarda derleme varyantı (dolayısıyla da daraltıcı tarafından kaldırılmaz) ancak zarar görmeyeceğini biliyorsunuz. belirtilen derleme varyantı için kullanılır. Oluşturma araçları kendiliğinden bir kaynağı yanlış belirlemiş olabilir; bu durumda da derleyici, kaynak kimliklerini satır içi olarak ekler. Ardından, kaynak analiz edici gerçekten referans verilen bir kaynak ile tam sayı değeri arasındaki farkı bilme kodda aynı değere sahip olan sayfalardır.

Katı referans kontrollerini etkinleştir

Normalde, kaynak daraltıcılar bir kaynağın bu düzenlemelerin nedenlerinden biri. Ancak, kodunuz Resources.getIdentifier(). (veya kitaplıklarınızdan herhangi biri bunu yapıyorsa: AppCompat kitaplığının nasıl çalıştığına bağlı olarak, bu, kodunuzun temel olarak dizeleri temsil eder. Bunu yaptığınızda kaynak daraltıcı, varsayılan olarak savunmaya sahiptir ve eşleşen ad biçimiyle tüm kaynakları potansiyel olarak kullanılır ve kaldırılamaz.

Örneğin, aşağıdaki kod img_ ön ek kullanıldı olarak işaretlenecek.

Kotlin

val name = String.format("img_%1d", angle + 1)
val res = resources.getIdentifier(name, "drawable", packageName)

Java

String name = String.format("img_%1d", angle + 1);
res = getResources().getIdentifier(name, "drawable", getPackageName());

Kaynak daraltıcı, hesabınızdaki tüm dize sabitlerine de bakar. ve çeşitli res/raw/ kaynaklarını tarayan ve Şuna benzer bir biçimdeki URL'ler: file:///android_res/drawable//ic_plus_anim_016.png. Bulduğunda URL'leri oluşturmak için kullanılabilecekmiş gibi görünen bunun gibi dizeler bu nedenle onları kaldırmaz.

Bunlar, varsayılan olarak etkinleştirilen güvenli küçültme moduna örneklerdir. Ancak bu ayarı "pişman olmaktan iyidir" şeklinde kapatabilirsiniz. ve en iyi uygulamaları yalnızca kullanıldığından emin olduğu kaynakların tutulacağını belirtmelidir. Alıcı: Bunu yapmak için shrinkMode öğesini strict keep.xml dosyası için aşağıdaki gibidir:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:shrinkMode="strict" />

Katı daraltma modunu etkinleştirirseniz kodunuz aynı zamanda dizeleri dinamik olarak oluşturulan dizelere sahip kaynaklar için bu kaynakları tools:keep özelliğini kullanarak manuel olarak saklayın.

Kullanılmayan alternatif kaynakları kaldırın

Gradle kaynak daraltıcı, yalnızca referans verilmeyen kaynakları kaldırır uygulama kodunuz tarafından yapılır, yani farklı cihaz yapılandırmaları için alternatif kaynaklar başlıklı makaleye bakın. Gerekirse Android Gradle eklentisinin resConfigs özelliğini kullanarak uygulamanızın ihtiyaç duymadığı alternatif kaynak dosyalarını kaldırın.

Örneğin, dil kaynakları içeren bir kitaplık kullanıyorsanız (ör. AppCompat veya Google Play Hizmetleri) kullanıyorsanız söz konusu kitaplıklardaki iletiler için çevrilmiş dil dizeleri uygulamanızın geri kalanının aynı dillere çevrilip çevrilmediğini kontrol edebilirsiniz. Raporlarınızdaki yalnızca uygulamanızın resmi olarak desteklediği dilleri tutun. bu dilleri resConfig özelliğini kullanarak bulabilirsiniz. Proje yönetimiyle ilgili belirtilmeyen diller kaldırılır.

Aşağıdaki snippet'te dil kaynaklarınızı yalnızca İngilizce ve Fransızca:

Kotlin

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

Eski

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

Bir uygulamayı varsayılan olarak yalnızca Android App Bundle biçimini kullanarak yayınlarken Kullanıcının cihazında yapılandırılan diller uygulama yüklenirken indirilir. Benzer şekilde, yalnızca cihazın ekran yoğunluğuyla eşleşen kaynaklar ve yerel cihazın ABI'si ile eşleşen kitaplıklar indirme işlemine dahil edilir. Daha fazla Android Uygulaması Paket yapılandırması.

APK'larla yayınlanan (Ağustos 2021'den önce oluşturulan) eski uygulamalar için: APK'nıza dahil edilecek ekran yoğunluğunu veya ABI kaynaklarını özelleştirmek için birden fazla APK oluşturma her biri farklı bir cihaz yapılandırmasını hedefliyor.

Yinelenen kaynakları birleştirme

Gradle varsayılan olarak aynı şekilde adlandırılmış kaynakları da birleştirir. Örneğin: farklı kaynak klasörlerinde bulunabilecek aynı ada sahip çekilebilirler. Bu davranışı shrinkResources mülkü tarafından kontrol edilmez ve birçok anahtar kelime olduğunda hatalardan kaçınmak gerektiği için kaynak adları kodunuzun aradığı adla eşleşir.

Kaynak birleştirme, yalnızca iki veya daha fazla dosya aynı dosyayı paylaştığında gerçekleşir Kaynak adı, türü ve niteleyicisi. Gradle hangi dosyayı dikkate alacağını tekrarlar arasında en iyi seçenek olmalıdır (açıklanan öncelik sırasına göre aşağıda yer alır) ve yalnızca bu kaynağı AAPT'ye iletir. yardımcı olur.

Gradle, aşağıdaki konumlarda yinelenen kaynaklar olup olmadığını kontrol eder:

  • Ana kaynak grubuyla ilişkili ana kaynaklar, src/main/res/ adresinde bulunuyor.
  • Derleme türü ve derleme çeşitlerine ait varyant yer paylaşımları.
  • Kitaplık projesi bağımlılıkları.

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

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

Örneğin, hem ana kaynaklarınızda hem de kaynaklarınızda yinelenen bir kaynak görünüyorsa bir derleme türü olduğunu varsayalım. Gradle, derleme aromasını seçer.

Aynı kaynak grubunda aynı kaynaklar görünüyorsa Gradle birleştirilemez kaynak birleştirme hatası verir. Bu durum, birden fazla kaynak kümeleri, sourceSet özelliğindeki build.gradle.kts dosyası (örneğin, her ikisi de src/main/res/ ise) ve src/main/res2/ aynı kaynakları içeriyor.

Kodunuzu karartma

Kod karartma işleminin amacı, uygulamalarınızın adlarını kısaltarak uygulamanızın boyutunu küçültmektir. Sınıflarını, yöntemlerini ve alanlarını değiştirebilir. Bu örnekte kod karartma:

androidx.appcompat.app.ActionBarDrawerToggle$DelegateProvider -> a.a.a.b:
androidx.appcompat.app.AlertController -> androidx.appcompat.app.AlertController:
    android.content.Context mContext -> a
    int mListItemLayout -> O
    int mViewSpacingRight -> l
    android.widget.Button mButtonNeutral -> w
    int mMultiChoiceItemLayout -> M
    boolean mShowTitle -> P
    int mViewSpacingLeft -> j
    int mButtonPanelSideLayout -> K

Kod karartma özelliği kodu uygulamanızdan kaldırmasa da boyutta önemli ölçüde tasarruf sağlar birçok sınıf, yöntem ve alanı dizine ekleyen DEX dosyalarına sahip uygulamalarda görülebilir. Ancak kod karartma, kodunuzun farklı bölümlerini, belirli görevleri, için ek araçlar gerektirir. kod karartma işleminden sonra yığın izleme (stacktrace) karartılmış yığın izlemenin kodunu çözün.

Ayrıca, kodunuzda uygulamanızın yöntemleri tahmin edilebilir adlandırma kullanılıyorsa ve derslere odaklanmaktır. Örneğin, düşünmeyi kullanırken olarak kullanın ve bunlar için saklama kuralları hangi kodun saklanacağını özelleştirme ile ilgili bölüme bakın. Bu öğeler kuralları, R8'e bu kodu yalnızca uygulamanızın son DEX'inde tutmasını değil, aynı zamanda asıl adını değiştirmiyor.

Kodu karartılmış yığın izlemenin kodunu çözme

R8, kodunuzu kararttıktan sonra yığın izlemeyi anlamak zordur (imkansız değilse bile) çünkü sınıfların ve yöntemlerin adları değiştirildi. Orijinal yığın izlemeyi edinmek için yığın izlemeyi geri almasını sağlayın.

Kod optimizasyonu

R8, uygulamanızı daha da fazla optimize etmek için kodunuzu daha ayrıntılı kullanılmayan kodları kaldırın veya mümkün olduğunda, kodlarınızın %50'den fazla tekrar ayrıntılara girmiyor. Aşağıda, bu tür optimizasyonlara ilişkin birkaç örnek verilmiştir:

  • Kodunuz belirli bir if/else ifadesi için else {} dalını hiçbir zaman almazsa R8, else {} dalının kodunu kaldırabilir.
  • Kodunuz yalnızca birkaç yerde bir yöntemi çağırıyorsa R8 bu yöntemi kaldırabilir ve birkaç çağrı sitesine de satır içi olarak ekleyelim.
  • R8 bir sınıfın yalnızca bir benzersiz alt sınıfa sahip olduğunu ve örneklenmez (örneğin, yalnızca bir somut uygulama sınıfı), R8 ise iki sınıfı birleştirebilir ve Sınıfı uygulamadan kaldırabilirsiniz.
  • Daha fazla bilgi edinmek için Jake Wharton'ın R8 optimizasyonu blog yayınları

R8, ayrı optimizasyonları devre dışı bırakmanıza veya etkinleştirmenize ya da optimize edildiği anlamına gelir. Aslında R8, ProGuard kurallarını yok sayarak varsayılan optimizasyonları değiştirmek için (ör. -optimizations ve -optimizationpasses. Bu kısıtlama önemlidir, çünkü R8 optimizasyonlar için standart bir davranış sergilemek, Android'in Studio ekibi, karşılaşabileceğiniz sorunları kolayca giderir ve çözer.

Optimizasyonu etkinleştirmenin, bir uygulamadır. Örneğin, satır içine almak yığın çerçevelerini kaldırır. Bu bölümde, Orijinal yığın izlemeleri (stack trace) nasıl edineceğinizi öğrenmek için retracing başlıklı makaleyi inceleyin.

Çalışma zamanı performansı üzerindeki etkisi

Daraltma, kod karartma ve optimizasyon seçeneklerinin tümü etkinse R8 iyileşir kodun çalışma zamanı performansı (kullanıcı arayüzü iş parçacığında başlatma ve kare süresi dahil) bir şablondur. Bunlardan herhangi birini devre dışı bıraktığınızda, optimizasyon grubu önemli ölçüde bir örneğidir.

R8 etkinse Başlangıç Profilleri oluşturma başlangıç performansını da artırın.

Daha agresif optimizasyonları etkinleştirin

R8'de bir dizi ek optimizasyon ("tam mod" olarak adlandırılır) bu, ProGuard'dan farklı davranışlara neden olur. Bu optimizasyonlar, şu tarihten beri varsayılan: Android Gradle eklentisi 8.0.0 sürümü.

Bu ek optimizasyonları, aşağıdakileri ekleyerek devre dışı bırakabilirsiniz: projenizin gradle.properties dosyası:

android.enableR8.fullMode=false

Ek optimizasyonlar R8'in ProGuard'dan farklı davranmasına neden olduğundan, çalışma zamanından kaçınmak için ek ProGuard kuralları dahil etmenizi sorun yaşama olasılığınızı artırır. Örneğin, kodu, Java Reflection API aracılığıyla bir sınıfa referansta bulunuyor. Şu anda kullanılmıyor "tam mod" R8’de, bahsi geçen nesneleri incelemek ve değiştirmek o sınıfı çalışma sırasında kullanmaya başlar ve kodunuz olmasa bile otomatik olarak sınıfını ve statik başlatıcısını korur.

Ancak "tam mod" kullanılırken R8 bu varsayımda bulunmaz ve R8 kodunuzun çalışma zamanında sınıfı hiçbir zaman kullanmadığını iddia eder. Aksi takdirde, sınıfını da kullanır. Diğer bir deyişle, sınıfı ve statik başlatıcıyı kullanmak istiyorsanız, bu işlemi yapmak için gerekir.

R8'in "tam modunu" kullanırken herhangi bir sorunla karşılaşırsanız şuraya bakın: R8 SSS sayfası bir çözüm üretmeye çalışın. Sorunu çözemiyorsanız lütfen hata bildirin.

Yığın izlemeyi geri çekme

R8 tarafından işlenen kod, yığın izlemelere yol açabilecek çeşitli şekillerde değiştirilir anlaşılması daha zordur çünkü yığın izlemeler, kaynak koda tam olarak karşılık gelmeyecektir. Bu hata ayıklama bilgileri kullanılırken satır numaralarında saklanmaz. Satır içine alma ve özetleme gibi optimizasyonlardan kaynaklanıyor olabilir. İlgili içeriği oluşturmak için kullanılan en büyük faktör kod karartmadır. Sınıfların ve yöntemlerin bile Adları değiştirebilirsiniz.

R8, orijinal yığın izlemeyi kurtarmak için retrace komut satırı aracıdır. komut satırı araçları paketi ile birlikte sunulur.

Uygulamanızın yığın izlemelerinin geri alınmasını desteklemek için derleme için kurallarını modülünüzün proguard-rules.pro dosyasına ekleyin:

-keepattributes LineNumberTable,SourceFile
-renamesourcefileattribute SourceFile

LineNumberTable özelliği konum bilgilerini korur bu konumların yığın izlemede yazdırılacağı yöntemleri kullanın. SourceFile özelliği Tüm potansiyel çalışma zamanlarının konum bilgilerini gerçekten yazdırmasını sağlar. -renamesourcefileattribute yönergesi, yığındaki kaynak dosya adını ayarlar sadece SourceFile izler. Gerçek orijinal kaynak dosya adı şu değil: gerekir.

R8 her çalıştırıldığında bir mapping.txt dosyası oluşturur. Bu dosya, Yığın izlemeleri (stack trace) orijinaline eşleştirmek için gereken bilgileri içerir yığın izlemeleri içerir. Android Studio, dosyayı <module-name>/build/outputs/mapping/<build-type>/. dizin.

Uygulamanızı Google Play'de yayınlarken mapping.txt dosyasını yükleyebilirsiniz sürümdeki talimatları uygulayın. Android App Bundle'ları kullanarak yayınlarken bu dosyası otomatik olarak uygulama paketi içeriğine eklenir. Ardından Google Play, kullanıcı tarafından bildirilen sorunlardan gelen yığın izlemeleri (stack trace) takip eder. Böylece bunları Play Console'da inceleyebilirsiniz. Daha fazla bilgi için Yardım Merkezi'ne bakın bu adımların çökmeyle sonuçlanan yığın izlemelerin (stack trace) kodunu gösterme.

R8 ile sorun giderme

Bu bölümde, etkinleştirme sırasında karşılaşılan sorunları gidermeye yönelik bazı stratejiler açıklanmaktadır küçültme, kod karartma ve optimizasyon. Çözüm bulamazsanız daha fazla bilgi edinmek için R8 SSS sayfası ve ProGuard'ın sorun giderme kılavuzu.

Kaldırılan (veya saklanan) kod için rapor oluşturma

R8 ile ilgili belirli sorunları gidermenize yardımcı olması için R8'in uygulamanızdan kaldırdığı tüm kodları görebilirsiniz. Erişim sağlamak istediğiniz her modül için Bu raporu oluşturmak için özel raporunuza -printusage <output-dir>/usage.txt ekleyin: kuralları dosyası olarak kaydedebilirsiniz. R8'i etkinleştirip uygulamanızı derlediğinizde R8, belirttiğiniz yol ve dosya adına sahip bir rapor oluşturun. Kaldırılan kod raporu aşağıdaki gibi görünür:

androidx.drawerlayout.R$attr
androidx.vectordrawable.R
androidx.appcompat.app.AppCompatDelegateImpl
    public void setSupportActionBar(androidx.appcompat.widget.Toolbar)
    public boolean hasWindowFeature(int)
    public void setHandleNativeActionModesEnabled(boolean)
    android.view.ViewGroup getSubDecor()
    public void setLocalNightMode(int)
    final androidx.appcompat.app.AppCompatDelegateImpl$AutoNightModeManager getAutoNightModeManager()
    public final androidx.appcompat.app.ActionBarDrawerToggle$Delegate getDrawerToggleDelegate()
    private static final boolean DEBUG
    private static final java.lang.String KEY_LOCAL_NIGHT_MODE
    static final java.lang.String EXCEPTION_HANDLER_MESSAGE_SUFFIX
...

Bunun yerine, R8'in daha fazla bilgi edinmek için -printseeds <output-dir>/seeds.txt özel kurallar dosyası. R8'i etkinleştirip uygulamanızı derlediğinizde R8 çıkışları belirttiğiniz yol ve dosya adına sahip bir rapor oluşturun. Korunan giriş raporu şuna benzer:

com.example.myapplication.MainActivity
androidx.appcompat.R$layout: int abc_action_menu_item_layout
androidx.appcompat.R$attr: int activityChooserViewStyle
androidx.appcompat.R$styleable: int MenuItem_android_id
androidx.appcompat.R$styleable: int[] CoordinatorLayout_Layout
androidx.lifecycle.FullLifecycleObserverAdapter
...

Kaynak daraltma sorunlarını giderme

Kaynakları küçülttüğünüzde Oluşturma açılan pencerede kaynaklardan kaldırılır. (Önce Görünümü aç/kapat'ı tıklamanız gerekir tıklayın.) Örnek:

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

Gradle, aynı zamanda resources.txt adında bir teşhis dosyası da oluşturur. <module-name>/build/outputs/mapping/release/ (aynı dosyasını ProGuard'ın çıkış dosyaları olarak kaydeder). Bu dosya, diğer kaynaklara başvurduğunu ve hangi kaynakların emin olun.

Örneğin, @drawable/ic_plus_anim_016 adlı satıcının neden uygulamanızda, resources.txt dosyasını açın ve şunu arayın: dosya adı. Bu referansın başka bir kaynaktan kaynaklandığını görebilirsiniz: şöyle olur:

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 neden @drawable/add_schedule_fab_icon_anim olduğunu bilmeniz gerekiyor. erişilebilir bir kaynaktır. Yukarı doğru arama yaparsanız bu kaynağın "Kök erişilebilir kaynaklar şunlardır:". Yani, bir kod referansı var add_schedule_fab_icon_anim öğesine (yani R.drawable kimliği erişilebilir kodda bulunur).

Katı denetim kullanmıyorsanız kaynak kimlikleri erişilebilir olarak işaretlenebilir dize sabit değerleri varsa, dinamik olarak yüklenen kaynaklar için kaynak adları. Bu durumda, derleme çıkışını seçerseniz aşağıdaki gibi bir mesaj görebilirsiniz:

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

Bu dizelerden birini görürseniz ve dizenin daha fazla bilgi edinmek için tools:discard özelliğini kullanarak derleme sistemine öğeyi kaldırmasını bildirir, hangi kaynakların saklanacağını özelleştirme ile ilgili bölümde açıklandığı gibi.