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ç, kullanılmayan kodları ve kaynakları kaldırma, kod yeniden adlandırma veya sadeleştirme ve uygulama optimizasyonu için ölü kodu ve kaynak kaldırma işlemlerini gerçekleştiren derleyici olan R8 optimizasyon aracıdır.
R8'i etkinleştirmek, bir uygulamayı yayınlamaya hazırlarken önemli bir adımdı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 Öne Çıkarma Haftası videosuna göz atın.
Neden Keep kurallarına ihtiyaç duyulur?
Keep kurallarını yazma ihtiyacı temel bir çakışmadan kaynaklanır: R8 bir statik 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 kodu kullanılmayan olarak tanımlayıp kaldırır. Bu da çalışma zamanında kilitlenmelere neden olur.
Keep kuralı, R8 derleyicisine yönelik açık bir talimattır ve şunu belirtir: "Bu sınıf, yöntem veya alan, çalışma zamanında dinamik olarak erişilecek bir giriş noktasıdır. Doğrudan referansını bulamasanız bile bunu saklamanız gerekir."
Saklama kuralları hakkında daha fazla bilgi için resmi kılavuza bakın.
Keep kurallarını nereye yazmalısınız?
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 uygulamanın 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 kümesini 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 Keep 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ını 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 olmak önemlidir. Bu anti-pattern'ler genellikle yanlış anlamalardan veya sorun giderme kısayollarından kaynaklanır ve üretim derlemesinin performansı açısından felaketle sonuçlanabilir.
Genel seçenekler
Bu işaretler, yayınlanan derlemede asla 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ılırken tüm yeniden adlandırma işlemleri devre dışı bırakılır ve -dontshrink kullanılırken 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 performanslı 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ş kapsamlı 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 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 PROBLEMS
Ters çevirme operatörü (!)
Olumsuzluk 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 CAUTION
Bu kuralın "com.example.package içinde sınıf tutma" anlamına geldiğini düşünebilirsiniz. Ancak bu kural aslında "com.example.package içinde olmayan tüm uygulamadaki 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 önerilir.
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 kutudan çıkar çıkmaz ç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.
Kural en iyi uygulamaları
Neler yapmamanız gerektiğini öğrendiğinize göre şimdi en iyi uygulamalardan bahsedelim.
Dar kapsamlı Keep kuralları yazma
İyi saklama 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. |
| Yüksek: Yalnızca belirli bir sınıftaki 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 açıklama (ör. @Serialize) oluşturun ve alanlarının korunması gereken sınıfları "etiketlemek" için kullanın. Bu da başka bir temiz, bildirimsel ve son derece ölçeklenebilir 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 bildirimde 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 mevcut olduğu takdirde sınıf ve üyeleri korunur. |
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ş 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ı gerektiriyorsa 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
Daha fazla optimizasyon sağlamak için saklama kurallarının yanı sıra R8 yapılandırma dosyanıza genel işaretler de 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, R8'in daha agresif satır içi eklemeyi etkinleştirmek iç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 asla 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.
Kütüphaneler için 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 ardından kitaplığın AAR dosyası içinde otomatik olarak paketlenir.
android {
defaultConfig {
consumerProguardFiles("consumer-rules.pro")
}
...
}
Kitaplık tüketicileri 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 kurallarını 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ığı için "gizli" giriş noktaları yoktur ve bu nedenle Keep kurallarına gerek yoktur. 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 tam referans zincirini yazdırır. Böylece referansı izleyebilir ve kurallarınızı ayarlayabilirsiniz.
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 çalışmasının 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 Işığı Haftası'nı takip ederken YouTube'daki Işığı 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. Size yardım etmek için buradayız.
Avantajları kendiniz keşfetme zamanı.
Uygulamanızda 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 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 kazanç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.
Okumaya devam edin
-
Ürün Haberleri
Google Play'de mümkün olan en güvenli ve güvenilir deneyimi sunmak Bugün, kullanıcı gizliliğini artırmak ve işletmenizi sahtekarlıktan korumak için yeni bir dizi politika güncellemesi ve hesap aktarma özelliği duyuruyoruz.
Bennet Manuel • Okuma süresi: 3 dk.
-
Ürün Haberleri
Android Emulator ile çeşitli cihaz etkileşimlerini test etmek artık her zamankinden daha kolay.
Steven Jenkins • Okuma süresi: 2 dakika
-
Ürün Haberleri
Her geliştiricinin yapay zeka iş akışı ve ihtiyaçları benzersizdir. Bu nedenle, yapay zekanın geliştirme sürecinize nasıl yardımcı olacağını seçebilmeniz önemlidir. Ocak ayında, Android Studio'daki yapay zeka işlevlerine güç vermek için yerel veya uzak bir yapay zeka modeli seçme özelliğini kullanıma sunduk.
Matthew Warner • Okuma süresi: 2 dakika
Gelişmelerden haberdar olun
Android geliştirmeyle ilgili en son analizleri her hafta gelen kutunuza alın.