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()
veyaMethod.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
veyafinal
) 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>;
}