Saklama kuralları ekleme

Varsayılan ayarlarla uygulama optimizasyonunu etkinleştirdiğinizde R8, performans avantajlarınızı en üst düzeye çıkarmak için kapsamlı optimizasyonlar gerçekleştirir. R8, sınıf alanlarını ve yöntemlerini yeniden adlandırma, taşıma ve kaldırma da dahil olmak üzere kodda önemli değişiklikler yapar. Bu işlem hatalara neden olursa keep rules yazarak kodun hangi bölümlerinin değiştirilmeyeceğini belirtmeniz gerekir.

R8, aşağıdaki durumlarda kodu yanlışlıkla kaldırabilir veya değiştirebilir:

  • Yansıma: Yansıma kullanılarak erişilen kod (ör. Class.forName() veya Method.invoke() kullanılarak). R8 genellikle hangi sınıflara veya yöntemlere bu şekilde erişileceğini söyleyemez.
  • Serileştirme: Serileştirme ve serileştirmenin kaldırılması için gereken sınıflar veya alanlar, R8 için kullanılmamış gibi görünebilir (bu, yansımanın başka bir şeklidir).
  • Java Native Interface (JNI): Yerel koddan çağrılan Java yöntemleri. R8, Java'da ne çağırabileceğini görmek için yerel kodu analiz etmez.

Bu sayfada, R8'in optimizasyonlarının kapsamının nasıl sınırlanacağı açıklanmaktadır. Hangi kaynakların saklanacağını nasıl özelleştireceğinizi öğrenmek için Kaynaklar için saklama kuralları ekleme başlıklı makaleyi inceleyin.

Saklama kurallarını ekleme

Kurallarınızı modülün kök dizininde bulunan bir proguard-rules.pro dosyasına eklemeniz gerekir (Dosya zaten orada olabilir ancak yoksa oluşturun). Dosyadaki kuralları uygulamak için dosyayı modül düzeyindeki build.gradle.kts (veya build.gradle) dosyanızda aşağıdaki kodda gösterildiği gibi beyan etmeniz gerekir:

Kotlin

android {
    buildTypes {
        release {
            isMinifyEnabled = true
            isShrinkResources = true

            proguardFiles(
                // Default file with default optimization rules.
                getDefaultProguardFile("proguard-android-optimize.txt"),

                // File with your custom rules.
                "proguard-rules.pro"
            )
            ...
        }
    }
    ...
}

Groovy

android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true

            proguardFiles(
                // Default file with default optimization rules.
                getDefaultProguardFile('proguard-android-optimize.txt'),

                // File with your custom rules.
                'proguard-rules.pro'
            )
        }
    }
    // ...
}

Derleme komut dosyanız varsayılan olarak proguard-android-optimize.txt dosyasını da içerir. Bu dosya, çoğu Android projesi için gerekli olan kuralları içerir. Bu nedenle, bu dosyayı derleme komut dosyasında tutmanız gerekir.

Saklama kuralları nasıl yazılır?

R8, uygulama derleme sırasında uygulamanızın çağrı grafiğini analiz ederek uygulamada hangi kodun tutulması gerektiğini tespit eder. Bu çağrı grafiği, manifest girişlerinden (ör. etkinlikleriniz veya hizmetleriniz) başlar ve her uygulama ve kitaplık işlevi çağrısını izler. R8, bu şekilde doğrudan referans verilmeyen kodu kaldırır. Bu durum, çalıştırılan kod bu grafiğin bir parçası değilse (ör. yansıma yoluyla çağrılan kod) sorunlara neden olabilir. Kendi saklama kurallarınızı yazarak R8'e uygulamada kalması gereken kodu bildirebilirsiniz.

Saklama kuralı eklemek için proguard-rules.pro dosyasına bir -keep satırı ekleyin.

Kural söz dizimini koruma

Kurallar genellikle şu biçime uygun olmalıdır:

-<KeepOption> [OptionalModifier,...] <ClassSpecification> [{ OptionalMemberSpecification }]

Örneğin, belirli bir sınıfı ve tüm üyelerini korumak için aşağıdakileri kullanın:

-keep class com.myapp.MyClass { *; }

Daha fazla örnek için örnekler bölümüne bakın.

Saklama kuralı bileşenleri şunları yapar:

  • <KeepOption>, bir sınıfın hangi özelliklerinin korunacağını belirtmenize olanak tanır:

    Saklama seçeneği Açıklama

    -keep

    Sınıfı ve [{ OptionalMemberSpecification }] içinde listelenen üyeleri koruyun.

    -keepclassmembers

    Sınıfın optimizasyonuna izin verin. Sınıf korunursa [{ OptionalMemberSpecification }] içinde listelenen üyeleri de koruyun.

    -keepnames

    Sınıfın ve üyelerin kaldırılmasına izin verin ancak sınıfı gizlemeyin veya başka şekillerde değiştirmeyin.

    -keepclassmembernames

    Sınıfın ve üyelerin kaldırılmasına izin verin ancak üyeleri başka şekillerde gizlemeyin veya değiştirmeyin.

    -keepclasseswithmembers

    Üyeler belirtilen kalıpla eşleşirse sınıflar kaldırılmaz veya gizlenmez.

    En fazla optimizasyonu sağladığı için çoğunlukla -keepclassmembers kullanmanızı, gerekirse de -keepnames kullanmanızı öneririz. -keep, optimizasyona izin vermez. Bu nedenle, bu yöntemi az miktarda kullanmaya çalışın.

  • [OptionalModifier],...], bir sınıfın sıfır veya daha fazla Java dili değiştiricisini (ör. public veya final) listelemenizi sağlar.

  • <ClassSpecification>, saklama kuralının hangi sınıfa (veya hangi üst sınıfa ya da uygulanmış arayüze) uygulanacağını belirtmenizi sağlar. En basit durumda bu, tam nitelikli bir sınıftır.

  • [{ OptionalMemberSpecification }], tutma davranışını yalnızca belirli kalıplarla eşleşen sınıflar ve yöntemler olacak şekilde filtrelemenize olanak tanır. Amaçlanandan daha fazla saklamanın önüne geçmek için genellikle çoğu saklama kuralında bu önerilir.

Keep rule examples (Kural örneklerini sakla)

İyi tasarlanmış saklama kurallarına dair bazı örnekleri aşağıda bulabilirsiniz.

Alt sınıf oluşturma

Bu saklama kuralı, veritabanı kurucularının yansıtmayla oluşturulmasını sağlamak için androidx.room:room-runtime içine paketlenir.

-keep class * extends androidx.room.RoomDatabase { void <init>(); }

Android Framework'den yansıma ObjectAnimator

Bu tutma kuralı, ObjectAnimator'ın JNI ile yerel koddan alıcı veya ayarlayıcıları çağırabilmesini sağlamak için androidx.vectordrawable:vectordrawable-animated içine paketlenir. Oluşturma'daki yeni animasyon sistemlerinin bu tür kuralları gerektirmediğini unutmayın. Bu, kural yapısına dair yalnızca bir örnektir.

-keepclassmembers class androidx.vectordrawable.graphics.drawable.VectorDrawableCompat$* {
   void set*(***);
   *** get*();
}

JNI Kaydı

Bu saklama kuralı, yerel yöntemleri korumak için kullanılan androidx.graphics:graphics-path içine paketlenmiştir. Kitaplığınız yerel yöntemleri env->RegisterNatives() ile manuel olarak kaydediyorsa bu gerekli olabilir.

-keepclasseswithmembers class androidx.graphics.path.** {
    native <methods>;
}