Modern Android geliştirmede, küçük, hızlı ve güvenli bir uygulama sunmak temel bir kullanıcı beklentisidir. Android derleme sisteminin bunu başarmak için kullandığı birincil araç, R8 optimizasyon aracıdır. Bu derleyici, küçültme, kod yeniden adlandırma veya sadeleştirme ve uygulama optimizasyonu için kullanılmayan kod ve kaynak kaldırma işlemlerini gerçekleştirir.
R8'i etkinleştirmek, bir uygulamayı yayınlanmaya hazırlama sürecinde kritik bir adımdır ancak geliştiricilerin "Keep kuralları" şeklinde rehberlik sağlamasını gerektirir.
Bu makaleyi okuduktan sonra, YouTube'da R8 optimize ediciyi etkinleştirme, hata ayıklama ve sorun giderme ile ilgili Performance Spotlight Week videosuna göz atın.
Saklama kurallarına neden ihtiyaç duyulur?
Keep kuralları yazma ihtiyacı, temel bir çelişkiden kaynaklanır: R8 statik bir analiz aracıdır ancak Android uygulamaları genellikle yansıma gibi dinamik yürütme kalıplarına veya JNI (Java Yerel Arayüzü) kullanarak yerel kodun içine ve dışına yapılan çağrılara dayanır.
R8, doğrudan çağrıları analiz ederek kullanılan kodun grafiğini oluşturur. Koda dinamik bir şekilde erişildiğinde R8'in statik analizi bunu tahmin edemez ve bu kodu kullanılmayan olarak tanımlayıp kaldırır. Bu da çalışma zamanı kilitlenmelerine yol açar.
Saklama kuralı, R8 derleyicisine verilen açık bir talimattır: "Bu sınıf, yöntem veya alan, çalışma zamanında dinamik olarak erişilecek bir giriş noktasıdır. Doğrudan bir referans bulamasanız bile bu bilgiyi saklamanız gerekir."
Saklama kuralları hakkında daha fazla bilgi için resmi kılavuzu inceleyin.
Saklama kuralları nerede yazılır?
Bir uygulama için özel saklama kuralları metin dosyasına yazılır. Bu dosya, kural gereği proguard-rules.pro olarak adlandırılır ve uygulama veya kitaplık modülünün kök dizininde bulunur. Bu dosya daha sonra modülünüzün build.gradle.kts dosyasının release derleme türünde belirtilir.
release {
isShrinkResources = true
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
}Doğru varsayılan dosyayı kullanma
getDefaultProguardFile yöntemi, Android SDK tarafından sağlanan varsayılan kural grubunu içe aktarır. Yanlış dosya kullanıldığında uygulamanız optimize edilmeyebilir. proguard-android-optimize.txt kullandığınızdan emin olun. Bu dosya, standart Android bileşenleri için varsayılan saklama kurallarını sağlar ve R8'in kod optimizasyonlarını etkinleştirir. Eski proguard-android.txt yalnızca saklama kurallarını sağlar ancak R8'in optimizasyonlarını etkinleştirmez.
Bu ciddi bir performans sorunu olduğundan, Android Studio Narwhal 3 Feature Drop'tan itibaren geliştiricileri yanlış dosya kullanımı konusunda uyarmaya başlıyoruz. Ayrıca Android Gradle Eklentisi 9.0 sürümünden itibaren, eski proguard-android.txt dosyasını artık desteklemiyoruz. Bu nedenle, optimize edilmiş sürüme geçiş yaptığınızdan emin olun.
Saklama kuralları yazma
Saklama kuralı üç ana bölümden oluşur:
-keepveya-keepclassmembersgibi bir seçenekallowshrinkinggibi isteğe bağlı değiştiriciler- Eşleştirilecek kodu tanımlayan sınıf spesifikasyonu
Söz diziminin tamamı ve örnekler için Keep kuralları ekleme ile ilgili kılavuza bakın.
Saklama kuralı anti-pattern'leri
En iyi uygulamaların yanı sıra anti-pattern'leri de bilmek önemlidir. Bu anti-pattern'ler genellikle yanlış anlamalardan veya sorun giderme kısayollarından kaynaklanır ve üretim derlemesinin performansı açısından yıkıcı olabilir.
Genel seçenekler
Bu işaretler, yayınlanan derlemelerde asla kullanılmaması gereken genel açma/kapatma düğmeleridir. Yalnızca bir sorunu izole etmek için geçici olarak hata ayıklama amacıyla kullanılır.
-dontotptimize kullanıldığında R8'in performans optimizasyonları devre dışı bırakılır ve uygulama yavaşlar.
-dontobfuscate kullanıldığında tüm yeniden adlandırma işlemleri devre dışı bırakılır, -dontshrink kullanıldığında ise ölü kod kaldırma işlemi devre dışı bırakılır. Bu genel kuralların her ikisi de uygulama boyutunu artırır.
Daha yüksek performanslı bir uygulama kullanıcı deneyimi için mümkün olduğunca bu global işaretleri üretim ortamında kullanmaktan kaçının.
Aşırı geniş saklama kuralları
R8'in avantajlarını geçersiz kılmanın en kolay yolu, aşırı geniş kapsamlı saklama kuralları yazmaktır. Aşağıdaki gibi saklama kuralları, R8 optimize ediciye bu paketteki veya alt paketlerindeki hiçbir sınıfı küçültmemesini, karartmamasını ve optimize etmemesini söyler. Bu, R8'in tüm paket için sağladığı avantajları tamamen ortadan kaldırır. Bunun yerine dar kapsamlı ve spesifik saklama kuralları yazmaya çalışın.
-keep class com.example.package.** { *;} // WIDE KEEP RULES CAUSE PROBLEMSTers çevirme operatörü (!)
Ters çevirme operatörü (!), bir paketi kuraldan hariç tutmanın etkili bir yolu gibi görünüyor. Ancak bu o kadar basit değil. Şu örneği ele alalım:
-keep class !com.example.my_package.** { *; } // USE WITH CAUTIONBu kuralın "com.example.package içindeki sınıfları saklama" anlamına geldiğini düşünebilirsiniz. Ancak aslında "com.example.package içinde olmayan tüm uygulama genelindeki her sınıfı, yöntemi ve özelliği sakla " anlamına gelir. Bu durum sizi şaşırttıysa R8 yapılandırmanızda olumsuzlama olup olmadığını kontrol etmenizi öneririz.
Android bileşenleri için gereksiz kurallar
Sık yapılan bir diğer hata da uygulamanızın Activities, Services veya BroadcastReceivers için manuel olarak saklama kuralları eklemektir. Bu gereksizdir. Varsayılan proguard-android-optimize.txt dosyası, bu standart Android bileşenlerinin kullanıma hazır şekilde çalışması için gereken kuralları zaten içerir.
Ayrıca birçok kitaplık kendi saklama kurallarını getirir. Bu nedenle, bunlar için kendi kurallarınızı yazmanız gerekmez. Kullandığınız bir kitaplıktaki saklama kurallarıyla ilgili sorun varsa sorunun ne olduğunu öğrenmek için kitaplık yazarıyla iletişime geçmeniz önerilir.
Saklama kuralıyla ilgili en iyi uygulamalar
Nelerden kaçınmanız gerektiğini öğrendiğinize göre, şimdi en iyi uygulamalardan bahsedelim.
Dar kapsamlı saklama kuralları yazma
İyi saklama kuralları, mümkün olduğunca dar kapsamlı ve spesifik olmalıdır. Yalnızca gerekli olanları korumalı, diğer her şeyi R8'in optimize etmesine izin vermelidirler.
| Kural | Kalite |
|---|---|
| Düşük: Bir paketin tamamını ve alt paketlerini saklar. |
| Düşük: Sınıfın tamamını korur. Bu sınıf muhtemelen hâlâ çok geniştir. |
-keepclassmembers class com.example.MyClass {
private java.lang.String secretMessage;
public void onNativeEvent(java.lang.String);
} | Yüksek: Yalnızca belirli bir sınıftaki alakalı yöntemler ve özellikler korunur. |
Ortak üst öğeleri kullanma
Birden fazla farklı veri modeli için ayrı saklama kuralları yazmak yerine, ortak bir temel sınıfı veya arayüzü hedefleyen tek bir kural yazın. Aşağıdaki kural, R8'e bu arayüzü uygulayan sınıfların tüm üyelerini tutmasını söyler ve yüksek düzeyde ölçeklenebilirdir.
# Keep all fields of any class that implements SerializableModel
-keepclassmembers class * implements com.example.models.SerializableModel {
<fields>;
}Birden fazla sınıfı hedeflemek için notları kullanma
Özel bir ek açıklama (ör. @Serialize) oluşturun ve bunu, alanlarının korunması gereken sınıfları "etiketlemek" için kullanın. Bu da başka bir temiz, açıklayıcı ve yüksek düzeyde ölçeklenebilir kalıptır. Kullandığınız çerçevelerdeki mevcut ek açıklamalar için de saklama kuralları oluşturabilirsiniz.
# Keep all fields of any class annotated with @Serialize
-keepclassmembers class * {
@com.example.annotations.Serialize <fields>;
}Doğru saklama seçeneğini belirleme
Saklama seçeneği, kuralın en önemli kısmıdır. Yanlış seçeneği belirlemek, optimizasyonun gereksiz yere devre dışı bırakılmasına neden olabilir.
| Keep seçeneği | İşlevi |
-keep | Bildirimde belirtilen sınıfın ve üyelerin kaldırılmasını veya yeniden adlandırılmasını engeller. |
-keepclassmembers | Belirtilen üyelerin kaldırılmasını veya yeniden adlandırılmasını engeller ancak sınıfın kendisinin kaldırılmasına izin verir. Bu işlem yalnızca başka bir şekilde kaldırılmamış sınıflarda yapılabilir. |
-keepclasseswithmembers | Kombinasyon: Yalnızca belirtilen tüm üyeler mevcutsa sınıfı ve üyelerini korur. |
Saklama seçeneği hakkında daha fazla bilgiyi Saklama Seçenekleri ile ilgili dokümanlarımızda bulabilirsiniz.
Değiştiricilerle optimizasyona izin ver
allowshrinking ve allowobfuscation gibi değiştiriciler, geniş bir -keep kuralını esneterek optimizasyon gücünü R8'e geri verir. Örneğin, eski bir kitaplık sizi tüm bir sınıfta -keep kullanmaya zorluyorsa küçültme ve kod karartmaya izin vererek optimizasyonun bir kısmını geri kazanabilirsiniz:
# Keep this class, but allow R8 to remove it if it's unused and allow R8 to rename it. -keep,allowshrinking,allowobfuscation class com.example.LegacyClass
Ek optimizasyon için genel seçenekler ekleme
Saklama kurallarının yanı sıra, daha fazla optimizasyon için R8 yapılandırma dosyanıza genel işaretler ekleyebilirsiniz.
-repackageclasses, R8'e tüm kod karartılmış sınıfları tek bir pakete taşıma talimatı veren güçlü bir seçenektir. Bu sayede, gereksiz paket adı dizeleri kaldırılarak DEX dosyasında önemli ölçüde yer tasarrufu sağlanır.
-allowaccessmodification, R8'in daha agresif satır içi eklemeyi etkinleştirmek için erişimi genişletmesine (ör. private - public) olanak tanır. Bu özellik artık proguard-android-optimize.txt kullanılırken varsayılan olarak etkindir.
Uyarı: Kitaplık yazarları, bu genel optimizasyon işaretlerini tüketici kurallarına asla eklememelidir. Aksi takdirde, bu işaretler tüm uygulamaya zorunlu olarak uygulanır.
Bu durumu daha da netleştirmek için Android Gradle eklentisinin 9.0 sürümünde, kitaplıklardaki genel optimizasyon işaretlerini tamamen yok saymaya başlayacağız.
Kitaplıklar için en iyi uygulamalar
Her Android uygulaması şu veya bu şekilde kitaplıklardan yararlanır. Şimdi kütüphanelerle ilgili en iyi uygulamalardan bahsedelim.
Kitaplık geliştiricileri için
Kitaplığınızda yansıma veya JNI kullanılıyorsa gerekli saklama kurallarını tüketicilerine sağlamak sizin sorumluluğunuzdadır. Bu kurallar bir consumer-rules.pro dosyasına yerleştirilir ve ardından otomatik olarak kitaplığın AAR dosyasında paketlenir.
android {
defaultConfig {
consumerProguardFiles("consumer-rules.pro")
}
...
}Kitaplık kullanıcıları için
Sorunlu saklama kurallarını filtreleme
Sorunlu Keep kuralları içeren bir kitaplık kullanmanız gerekiyorsa AGP 9.0'dan itibaren bunları build.gradle.kts dosyanızda filtreleyebilirsiniz. Bu, R8'e belirli bir bağımlılıktan gelen kuralları yoksaymasını söyler.
release {
optimization.keepRules {
// Ignore all consumer rules from this specific library
it.ignoreFrom("com.somelibrary:somelibrary")
}
}En iyi saklama kuralı, saklama kuralı olmamasıdır
En iyi R8 yapılandırma stratejisi, saklama kuralları yazma ihtiyacını tamamen ortadan kaldırmaktır. Birçok uygulama için bu, yansıma yerine kod oluşturmayı tercih eden modern kitaplıklar seçilerek sağlanabilir. Kod oluşturma sayesinde optimize edici, çalışma zamanında hangi kodun kullanıldığını ve hangi kodun kaldırılabileceğini daha kolay belirleyebilir. Ayrıca, dinamik yansıtma kullanılmaması "gizli" giriş noktalarının olmadığı ve bu nedenle Keep kurallarına gerek olmadığı anlamına gelir. Yeni bir kitaplık seçerken her zaman yansıma yerine kod oluşturma kullanan bir çözümü tercih edin.
Kitaplık seçme hakkında daha fazla bilgi için Kitaplıkları akıllıca seçme başlıklı makaleyi inceleyin.
R8 yapılandırmanızda hata ayıklama ve sorun giderme
R8, tutması gereken kodu kaldırdığında veya APK'nız beklenenden daha büyük olduğunda sorunu teşhis etmek için bu araçları kullanın.
Yinelenen ve genel saklama kurallarını bulma
R8, onlarca kaynaktan gelen kuralları birleştirdiği için "nihai" kural kümesinin ne olduğunu bilmek zor olabilir. Bu işareti proguard-rules.pro dosyanıza eklediğinizde eksiksiz bir rapor oluşturulur:
# Outputs the final, merged set of rules to the specified file -printconfiguration build/outputs/logs/configuration.txt
Gereksiz kuralları bulmak veya sorunlu bir kuralı (ör. -dontoptimize) içeren belirli kitaplığa kadar izlemek için bu dosyada arama yapabilirsiniz.
R8'e sorun: Bunu neden saklıyorsunuz?
Kaldırılmasını beklediğiniz bir sınıf hâlâ uygulamanızda görünüyorsa R8 bunun nedenini size söyleyebilir. Şu kuralı eklemeniz yeterlidir:
# Asks R8 to explain why it's keeping a specific class class com.example.MyUnusedClass -whyareyoukeeping
Derleme sırasında R8, bu sınıfı tutmasına neden olan tam referans zincirini yazdırır. Böylece referansı izleyebilir ve kurallarınızı düzenleyebilirsiniz.
Tam kılavuz için R8 sorunlarını giderme bölümüne göz atın.
Sonraki adımlar
R8, Android uygulama performansını artırmak için güçlü bir araçtır. Etkinliği, statik analiz motoru olarak işleyişinin doğru anlaşılmasına bağlıdır.
Üye düzeyinde belirli kurallar yazarak, üst öğelerden ve ek açıklamalardan yararlanarak ve doğru saklama seçeneklerini dikkatlice belirleyerek tam olarak gerekli olan verileri saklayabilirsiniz. En gelişmiş uygulama, yansıma tabanlı öncülleri yerine modern, kod oluşturma tabanlı kitaplıkları seçerek kurallara olan ihtiyacı tamamen ortadan kaldırmaktır.
Performans Öne Çıkanlar Haftası'nı takip ederken YouTube'daki bugünkü Öne Çıkanlar Haftası videosuna göz atmayı ve R8 yarışmamıza devam etmeyi unutmayın. R8'i etkinleştirme veya sorun giderme ile ilgili sorularınız için #optimizationEnabled etiketini kullanın. Yardımcı olmaya hazırız.
Avantajları kendiniz görme zamanı geldi.
Uygulamanız için R8 tam modunu bugün etkinleştirmenizi öneririz.
- Başlamak için geliştirici kılavuzlarımızı inceleyin: Uygulama optimizasyonunu etkinleştirme.
- Hâlâ
proguard-android.txtkullanıp kullanmadığınızı kontrol edin veproguard-android-optimize.txtile değiştirin. - Ardından etkiyi ölçün. Farkı yalnızca hissetmekle kalmayın, doğrulayın. Başlatma sürelerinizi öncesi ve sonrası olarak ölçmek için GitHub'daki Macrobenchmark örnek uygulamamızın kodunu uyarlayarak performans artışınızı ölçün.
Uygulamanızın performansında önemli bir iyileşme göreceğinizden eminiz.
Bu arada, sorularınızı sormak için #AskAndroid sosyal etiketini kullanabilirsiniz. Uzmanlarımız hafta boyunca sorularınızı takip edip yanıtlayacak.
Yarın, Temel ve Başlangıç Profilleri ile Profile Göre Optimizasyon'dan bahsedecek, Compose oluşturma performansının son sürümlerde nasıl iyileştirildiğini ve arka plan çalışmalarıyla ilgili performans konularını paylaşacağız.
-
Ürün HaberleriYakında çıkacak Android sürümünü hedefleyen uygulamalar artık WRITE_CONTACTS izniyle kişilere doğrudan yazamayacak.
Roxanna Aliabadi Walker • Okuma süresi: 6 dk. -
Ürün HaberleriTemsilci tabanlı geliştirme hızlandıkça Android mühendisliği heyecan verici yeni bir aşamaya geçiyor: yardımcı kod tamamlamadan, sizin yönlendirmenizle uçtan uca yürütülen temsilcilere geçiş. Kullandığınız modeller ve temsilciler konusunda tam bir seçim özgürlüğüne ve esnekliğe sahipsiniz.
Jason Buchel • Okuma süresi: 3 dk. -
Ürün HaberleriBugün, "bir mağazadan daha fazlası" vizyonumuzu bir sonraki aşamaya nasıl taşıdığımızı paylaştık. Google Play, aylık 250 milyondan fazla etkin kullanıcının kişisel ana sayfası olan Siz sekmesinden 700 milyondan fazla oyuncu profilini birbirine bağlayan birleşik oyun platformumuza kadar her yerde kullanıcılarla buluşuyor.
Paul Feng • Okuma süresi: 3 dk.
Android geliştiriciliğiyle ilgili en son analizleri her hafta gelen kutunuza alın.