Modern Android geliştirmede, küçük, hızlı ve güvenli bir uygulama yayınlamak temel bir kullanıcı beklentisidir. Android derleme sisteminin bunu sağlamak için kullandığı temel araç, küçültme, kod yeniden adlandırma veya sadeleştirme ve uygulama optimizasyonu için kullanılmayan kodları ve kaynakları kaldıran derleyici olan R8 optimizasyon aracıdır.
R8'i etkinleştirmek, bir uygulamayı yayınlamaya hazırlamanın önemli bir adımıdır ancak geliştiricilerin "Keep Rules" şeklinde rehberlik sağlamasını gerektirir.
Bu makaleyi okuduktan sonra YouTube'da R8 optimize edicisini etkinleştirme, hata ayıklama ve sorun giderme ile ilgili Performans Haftasının Öne Çıkan Videosu'na göz atın.
Neden Keep kurallarına ihtiyaç duyulur?
Keep kurallarını yazma ihtiyacı temel bir çakışmadan kaynaklanır: R8, statik bir analiz aracıdır ancak Android uygulamaları genellikle yansıtma veya JNI (Java Native Interface) kullanılarak yerel kodda ve yerel koddan yapılan çağrılar gibi dinamik yürütme kalıplarına 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ında kilitlenmelere neden olur.
Keep kuralı, R8 derleyicisine verilen açık bir talimattır ve "Bu sınıf, yöntem veya alan, çalışma zamanında dinamik olarak erişilecek bir giriş noktasıdır. Doğrudan referans bulamasanız bile bunu saklamanız gerekir."
Keep Kuralları hakkında daha fazla bilgi için resmi kılavuza bakın.
Keep kurallarını yazabileceğiniz yerler
Bir uygulama için özel Keep kuralları metin dosyasına yazılır. Bu dosya, kural olarak 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ındaki 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 bir kural grubunu içe aktarır. Yanlış dosya kullanıldığında uygulamanız optimize edilmeyebilir. proguard-android-optimize.txt uzantısını 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ış dosyayı kullanma konusunda uyarmaya başlıyoruz. Ayrıca Android Gradle eklentisi 9.0 sürümünden itibaren eski proguard-android.txt dosyası desteklenmeyecek. Bu nedenle, optimize edilmiş sürüme yükselttiğinizden emin olun.
Keep 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 bir sınıf spesifikasyonu
Söz diziminin tamamı ve örnekler için Keep kuralları ekleme ile ilgili yönergelere bakın.
Keep kuralı anti-pattern'leri
En iyi uygulamaların yanı sıra anti-pattern'ler hakkında da bilgi sahibi olmanız önemlidir. Bu anti-pattern'ler genellikle yanlış anlamalardan veya sorun giderme kısayollarından kaynaklanır ve üretim derlemesinin performansı için felaketle sonuçlanabilir.
Genel seçenekler
Bu işaretler, yayınlanan derlemede hiçbir zaman kullanılmaması gereken genel açma/kapatma düğmeleridir. Yalnızca bir sorunu izole etmek için geçici hata ayıklama amacıyla kullanılırlar.
-dontotptimize kullanımı, R8'in performans optimizasyonlarını etkili bir şekilde devre dışı bırakarak uygulamanın yavaşlamasına neden olur.
-dontobfuscate kullanıldığında tüm yeniden adlandırma işlemleri devre dışı bırakılır ve -dontshrink kullanıldığında gereksiz kod kaldırma işlemi devre dışı bırakılır. Bu genel kuralların her ikisi de uygulama boyutunu artırır.
Daha iyi performans gösteren bir uygulama kullanıcı deneyimi için mümkün olduğunda bu genel işaretleri üretim ortamında kullanmaktan kaçının.
Gereğinden fazla geniş tutma kuralları
R8'in avantajlarını geçersiz kılmanın en kolay yolu aşırı geniş kapsamlı Keep kuralları yazmaktır. Aşağıdaki gibi kurallar, R8 optimize edicisinin bu paketteki hiçbir sınıfı veya alt paketlerinin hiçbirini küçültmemesini, karartmamasını ve optimize etmemesini sağlar. Bu, R8'in tüm paketteki avantajlarını tamamen kaldırır. Bunun yerine dar ve spesifik Keep kuralları yazmayı deneyin.
-keep class com.example.package.** { *;} // WIDE KEEP RULES CAUSE PROBLEMSTers çevirme operatörü (!)
Ters çevirme operatörü (!), bir paketi kuralın dışında bırakmak için etkili bir yöntem gibi görünüyor. Ancak bu o kadar basit değildir. Şu örneği ele alalım:
-keep class !com.example.my_package.** { *; } // USE WITH CAUTIONBu kuralın "sınıfları com.example.package içinde tutma" anlamına geldiğini düşünebilirsiniz. Ancak bu kural aslında "tüm uygulamada com.example.package içinde olmayan her sınıfı, yöntemi ve özelliği tut" anlamına gelir. Bu durum sizi şaşırttıysa R8 yapılandırmanızda olumsuzluk olup olmadığını kontrol etmeniz iyi olur.
Android bileşenleri için gereksiz kurallar
Diğer bir yaygın hata ise uygulamanızın Activities, Services veya BroadcastReceivers için saklama kurallarını manuel olarak eklemektir. Bu gereksizdir. Varsayılan proguard-android-optimize.txt dosyası, bu standart Android bileşenlerinin kullanıma hazır şekilde çalışması için gerekli 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 Keep Rules ile ilgili sorun varsa sorunun ne olduğunu öğrenmek için kitaplığın yazarıyla iletişime geçmeniz önerilir.
Keep Kuralı ile ilgili en iyi uygulamalar
Neler yapmamanız gerektiğini öğrendiğinize göre şimdi en iyi uygulamalardan bahsedelim.
Dar kapsamlı Keep kuralları yazma
İyi Keep kuralları mümkün olduğunca dar ve spesifik olmalıdır. Yalnızca gerekli olanları korumalı ve R8'in diğer her şeyi optimize etmesine izin vermelidir.
| Kural | Kalite |
|---|---|
| Düşük: Bir paketin tamamını ve alt paketlerini korur. |
| Düşük: Muhtemelen hâlâ çok geniş olan bir sınıfın tamamını korur. |
-keepclassmembers class com.example.MyClass {
private java.lang.String secretMessage;
public void onNativeEvent(java.lang.String);
} | Yüksek: Yalnızca belirli bir sınıfa ait alakalı yöntemler ve özellikler korunur. |
Ortak ataları kullanma
Birden fazla farklı veri modeli için ayrı 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 üyelerini tutmasını söyler ve oldukça ö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 ek açıklamaları kullanma
Özel bir ek açıklama (ör. @Serialize) oluşturun ve alanlarının korunması gereken sınıfları "etiketlemek" için kullanın. Bu da sade, bildirimsel ve son derece ölçeklenebilir bir başka kalıptır. Kullandığınız çerçevelerdeki mevcut notlar için de Keep kuralları oluşturabilirsiniz.
# Keep all fields of any class annotated with @Serialize
-keepclassmembers class * {
@com.example.annotations.Serialize <fields>;
}Doğru Keep seçeneğini belirleme
Kuralın en önemli kısmı, saklama seçeneğidir. Yanlış olanı seçmek, optimizasyonu gereksiz yere devre dışı bırakabilir.
| Keep Seçeneği | Ne yapar? |
-keep | Sınıfın ve beyanda belirtilen üyelerin kaldırılmasını veya yeniden adlandırılmasını önler. |
-keepclassmembers | Belirtilen üyelerin kaldırılmasını veya yeniden adlandırılmasını önler ancak sınıfın kendisinin kaldırılmasına izin verir. Bu işlem yalnızca başka şekilde kaldırılmayan sınıflarda yapılabilir. |
-keepclasseswithmembers | Birleştirme: Belirtilen tüm üyeler mevcutsa sınıf ve üyeleri korunur (yalnızca bu durumda). |
Saklama seçeneği hakkında daha fazla bilgiyi Saklama Seçenekleri dokümanımızda bulabilirsiniz.
Değiştiricilerle optimizasyona izin ver
allowshrinking ve allowobfuscation gibi değiştiriciler, geniş kapsamlı bir -keep kuralını gevşeterek optimizasyon gücünü R8'e geri verir. Örneğin, eski bir kitaplık tüm sınıfta -keep kullanmanızı zorunlu kılıyorsa küçültme ve karartmaya izin vererek bir miktar optimizasyon elde edebilirsiniz:
# 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 sağlamak için R8 yapılandırma dosyanıza genel işaretler ekleyebilirsiniz.
-repackageclasses, R8'e tüm karartılmış sınıfları tek bir pakete taşımasını söyleyen güçlü bir seçenektir. Bu, gereksiz paket adı dizelerini kaldırarak DEX dosyasında önemli ölçüde yer tasarrufu sağlar.
-allowaccessmodification, daha agresif satır içi genişletme sağlamak için R8'in erişimi genişletmesine (ör. private ile public) olanak tanır. Bu özellik, proguard-android-optimize.txt kullanılırken artık varsayılan olarak etkindir.
Uyarı: Kitaplık yazarları, bu genel optimizasyon işaretlerini tüketici kurallarına hiçbir zaman eklememelidir. Aksi takdirde, bu işaretler uygulamanın tamamına zorunlu olarak uygulanır.
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ıklarla ilgili en iyi uygulamalar
Her Android uygulaması, kitaplıklara bir şekilde bağımlıdır. Şimdi de kitaplıklarla ilgili en iyi uygulamalardan bahsedelim.
Kitaplık geliştiriciler için
Kitaplığınız yansıtma veya JNI kullanıyorsa tüketicilerine gerekli Keep kurallarını sağlama sorumluluğu size aittir. Bu kurallar, consumer-rules.pro dosyasına yerleştirilir ve bu dosya, kitaplığın AAR dosyası içinde otomatik olarak paketlenir.
android {
defaultConfig {
consumerProguardFiles("consumer-rules.pro")
}
...
}Kitaplık kullanıcıları için
Sorunlu Keep kurallarını filtreleme
Sorunlu Keep kuralları içeren bir kitaplık kullanmanız gerekiyorsa AGP 9.0'dan itibaren bu kuralları 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, Keep Rules yazma ihtiyacını tamamen ortadan kaldırmaktır. Birçok uygulama için, yansıtma yerine kod oluşturmayı tercih eden modern kitaplıklar seçilerek bu hedefe ulaşılabilir. Kod oluşturma sayesinde optimize edici, çalışma zamanında hangi kodun gerçekten kullanıldığını ve hangi kodun kaldırılabileceğini daha kolay belirleyebilir. Ayrıca dinamik yansıtma kullanılmadığında "gizli" giriş noktası olmaz. Bu nedenle Keep kuralları gerekmez. Yeni bir kitaplık seçerken her zaman yansıtma yerine kod oluşturma kullanan bir çözümü tercih edin.
Kitaplık seçme hakkında daha fazla bilgi için Kitaplık seçimiyle ilgili önemli noktalar 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 büyük olduğunda sorunu teşhis etmek için bu araçları kullanın.
Yinelenen ve genel Keep kurallarını bulma
R8, kuralları düzinelerce kaynaktan 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
Bu dosyada arama yaparak gereksiz kuralları bulabilir veya sorunlu bir kuralı (ör. -dontoptimize) onu içeren belirli kitaplığa kadar takip edebilirsiniz.
R8'e sorun: Bunu neden saklıyorsunuz?
Kaldırılmasını beklediğiniz bir sınıf uygulamanızda hâlâ varsa 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
R8, derleme sırasında bu sınıfı tutmasına neden olan referans zincirini tam olarak yazdırır. Böylece referansı izleyebilir ve kurallarınızı ayarlayabilirsiniz.
Tam kılavuz için R8 ile ilgili sorunları giderme bölümüne göz atın.
Sonraki adımlar
R8, Android uygulama performansını artırmak için kullanabileceğiniz 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 dikkatli bir şekilde seçerek tam olarak gerekli olanları saklayabilirsiniz. En gelişmiş uygulama, yansımaya dayalı olanların yerine modern, kod oluşturmaya dayalı kitaplıklar seçerek kurallara olan ihtiyacı tamamen ortadan kaldırmaktır.
Performans Öne Çıkarma Haftası'nı takip ederken YouTube'daki Öne Çıkarma Haftası videolarını izlemeyi ve R8 mücadelemize katılmayı unutmayın. R8'i etkinleştirme veya R8 ile ilgili sorun giderme hakkında sorularınız varsa #optimizationEnabled etiketini kullanın. Yardımcı olmaya hazırız.
Avantajları kendiniz keşfetme zamanı.
Uygulamanızda R8'i tam modda 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 ve kullanıyorsanızproguard-android-optimize.txtile değiştirin. - Ardından etkiyi ölçün. Farkı sadece hissetmeyin, doğrulayın. Başlangıç sürelerinizi önce ve sonra ölçmek için GitHub'daki Macrobenchmark örnek uygulamamızdaki kodu uyarlayarak performans artışlarınızı ölçün.
Uygulamanızın performansında önemli bir iyileşme göreceğinizden eminiz.
Sorularınızı iletmek için #AskAndroid sosyal medya etiketini kullanabilirsiniz. Uzmanlarımız hafta boyunca sorularınızı takip edip yanıtlar.
Yarın, temel ve başlangıç profilleriyle profile guided optimization hakkında konuşacağımız, Compose oluşturma performansının son sürümlerde nasıl iyileştiğini ve arka plan çalışmasıyla ilgili performans değerlendirmelerini paylaşacağımız için bizi takip etmeye devam edin.
-
Ürün HaberleriBugün, AndroidX Security State 1.1.0 sürümü ve Security State Provider 1.0.0 sürümü kitaplıklarının kararlı sürümünü duyurmaktan heyecan duyuyoruz.
Maunik Shah, Alec Garcia, Joseph Yong • Okuma süresi 4 dakika -
Ürün HaberleriBugün, mühendislerin tamamlaması birkaç gün hatta bir hafta süren, büyük ölçüde karmaşık görevler olan ilk uzun vadeli görevler (LHT) setini yayınlıyoruz. Ayrıca, ilgili model sağlayıcıların temsilcileriyle başlayarak temsilci tabanlı değerlendirmeyi de kullanıma sunuyoruz.
Matthew McCullough • Okuma süresi 3 dakika -
Ürün HaberleriAndroid'de kablosuz hata ayıklama artık her zamankinden daha hızlı, daha güvenilir ve daha kolay kuruluyor. ADB Wi-Fi 2.0 ile, kullanılabilirlik eksiklikleriyle ilgili geliştirici geri bildirimlerini doğrudan ele almak için yeni bir sunucu yığını ve daha akıllı ağ işleme özelliği sunuyoruz.
Steven Jenkins, Sherif Eid, Fabien Sanglard • Okuma süresi 1 dakika
Android geliştirmeyle ilgili en son analizleri her hafta gelen kutunuza alın.