Kitaplıkları akıllıca seçin

Uygulama optimizasyonunu etkinleştirmek için Android optimizasyonuyla uyumlu kitaplıklar kullanmanız gerekir. Bir kitaplık, Android optimizasyonu için yapılandırılmamışsa (örneğin, ilişkili saklama kurallarını paketlemeden yansıma kullanıyorsa) Android uygulaması için uygun olmayabilir. Bu sayfada, bazı kitaplıkların uygulama optimizasyonu için neden daha uygun olduğu açıklanmakta ve seçim yapmanıza yardımcı olacak genel ipuçları verilmektedir.

Kitaplık seçerken dikkat edilmesi gereken genel noktalar

Kitaplıklarınızın uygulama optimizasyonuyla uyumlu olmasını sağlamak için bu ipuçlarından yararlanın.

Yansıma yerine kod oluşturmayı tercih etme

Yansıma yerine kod oluşturma (codegen) kullanan kitaplıkları seçin. Kod oluşturma sayesinde optimize edici, çalışma zamanında hangi kodun kullanıldığını ve hangi kodun kaldırılabileceğini belirleyebilir. Bir kitaplığın kod oluşturma mı yoksa yansıma mı kullandığını anlamak zor olabilir ancak bazı işaretler vardır. Yardım için ipuçlarına bakın.

Kod oluşturma ve yansıma hakkında daha fazla bilgi için Kitaplık yazarları için optimizasyon başlıklı makaleyi inceleyin.

Yansıma kullanımını kontrol etme (gelişmiş)

Bir kitaplığın yansıma kullanıp kullanmadığını kodunu inceleyerek anlayabilirsiniz. Kitaplıkta yansıma kullanılıyorsa ilişkili saklama kuralları sağladığından emin olun. Bir kitaplık, aşağıdaki işlemleri yapıyorsa büyük olasılıkla yansıma kullanıyordur:

  • kotlin.reflect veya java.lang.reflect paketlerindeki sınıfları ya da yöntemleri kullanır.
  • Class.forName veya classLoader.getClass işlevlerini kullanır.
  • Çalışma zamanında ek açıklamaları okur. Örneğin, val value = myClass.getAnnotation() veya val value = myMethod.getAnnotation() kullanarak bir ek açıklama değeri depolayıp ardından value ile bir işlem yapar.
  • Yöntemleri, yöntem adını dize olarak kullanarak çağırır. Aşağıdaki örnekte bu durum gösterilmektedir:

    // Calls the private `processData` API with reflection
    myObject.javaClass.getMethod("processData", DataType::class.java)
    ?.invoke(myObject, data)
    

Optimizasyon sorunlarını kontrol etme

Yeni bir kitaplık kullanmayı düşünüyorsanız kitaplığın sorun izleyicisini ve online tartışmaları inceleyerek sadeleştirme veya uygulama optimizasyonunu yapılandırmayla ilgili sorunlar olup olmadığını kontrol edin. Böyle bir durum varsa o kitaplığın alternatiflerini bulmaya çalışmalısınız. Aşağıdakilere dikkat edin:

  • AndroidX kitaplıkları ve Hilt gibi kitaplıklar, çoğunlukla yansıma yerine kod oluşturma kullandıkları için uygulama optimizasyonuyla iyi çalışır. Yansıma kullandıklarında, yalnızca gerekli kodu saklamak için minimum saklama kuralları sağlarlar.
  • Serileştirme kitaplıkları, nesneleri örneklendirirken veya serileştirirken ortak metin kodundan kaçınmak için genellikle yansımayı kullanır. Yansıma tabanlı yaklaşımlar (JSON için Gson gibi) yerine, bu sorunları önlemek için kod oluşturma kullanan kitaplıkları (ör. Kotlin Serialization veya kod oluşturma ile Moshi) tercih edin.
  • Mümkünse paket genelinde saklama kuralları içeren kitaplıklardan kaçının. Paket genelindeki saklama kuralları hataların çözülmesine yardımcı olabilir ancak geniş kapsamlı saklama kuralları, yalnızca gerekli kodu saklayacak şekilde hassaslaştırılmalıdır. Daha fazla bilgi için Optimizasyonları kademeli olarak uygulama başlıklı makaleyi inceleyin.
  • Üçüncü taraf kitaplığı kullanan bir uygulamayı yayınlamadan önce R8 Yapılandırma Analiz Aracı'nı kullanarak sağlanan saklama kurallarını denetleyin. Raporu inceleyerek kitaplığın saklama kurallarının aşırı geniş olup olmadığını ve R8'in kod tabanınızda kritik optimizasyonlar yapmasını engelleyip engellemediğini doğrulayabilirsiniz. Bu kontrol, seçtiğiniz kitaplıkların uygulamanızın performans hedefleriyle uyumlu olmasını ve gereksiz yapılandırma yükü oluşturmamasını sağlar.
  • Kitaplıklar, dokümanlardaki saklama kurallarını projenizdeki bir dosyaya kopyalayıp yapıştırmanızı gerektirmemelidir. Özellikle paket genelindeki saklama kuralları için bu geçerlidir. Bu kurallar, uzun vadede uygulama geliştirici için bakım yükü oluşturur ve zaman içinde optimize edilmesi ve değiştirilmesi zordur.

Yeni bir kitaplık ekledikten sonra optimizasyonu etkinleştirme

Yeni bir kitaplık eklediğinizde optimizasyonu etkinleştirin ve hata olup olmadığını kontrol edin. Hata varsa ilgili kitaplığın alternatiflerini arayın veya saklama kuralları yazın. Bir kitaplık optimizasyonla uyumlu değilse ilgili kitaplıkla ilgili hata bildiriminde bulunun.

Kötü saklama kurallarını filtreleme (gelişmiş)

Saklama kuralları birbirine eklenerek uygulanır. Bu, kitaplık bağımlılığının içerdiği belirli kuralların kaldırılamayacağı ve uygulamanızın diğer bölümlerinin derlenmesini etkileyebileceği anlamına gelir. Örneğin, bir kitaplıkta kod optimizasyonlarını devre dışı bırakma kuralı varsa bu kural, projenizin tamamı için optimizasyonları devre dışı bırakır.

Gerçekten kaldırılması gereken kodları tutan saklama kurallarına sahip kitaplıklardan kaçınmalısınız. Ancak bunları kullanmanız gerekiyorsa kuralları aşağıdaki kodda gösterildiği gibi filtreleyebilirsiniz:

// If you're using AGP 8.4 and higher
buildTypes {
    release {
        optimization.keepRules {
          it.ignoreFrom("com.somelibrary:somelibrary")
        }
    }
}

// If you're using AGP 7.3-8.3
buildTypes {
    release {
        optimization.keepRules {
          it.ignoreExternalDependencies("com.somelibrary:somelibrary")
        }
    }
}

Geniş kapsamlı kitaplık kuralları için önerilen iş akışı

R8 Configuration Analyzer, bir kitaplığın aşırı geniş saklama kuralları içerdiğini gösteriyorsa bu kuralları üretim derlemelerinde değil, yalnızca yerel derlemelerde filtreleyin. Kuralların uygulamanızı ne kadar etkilediğini test etmek için aşağıdaki adımları uygulayın:

  1. Kitaplığı güncelleyin: R8 Configuration Analyzer'ın işaretlediği kitaplığın en yeni sürümünü kullandığınızdan emin olun. Daha yeni sürümler, daha dar kapsamlı tüketici saklama kuralları içerebilir. En yeni sürümü bulmak için kitaplığın belgelerini veya Maven deposunu kontrol edin. Android Studio, birçok bağımlılığın daha yeni sürümlerini de işaretler. Güncelleme yaptıktan sonra R8 Yapılandırma Analiz Aracı'nı tekrar çalıştırarak geniş kapsamlı saklama kurallarının hâlâ geçerli olup olmadığını kontrol edin.
  2. Yerel olarak potansiyel iyileştirmeyi kontrol edin: Kitaplığın paketlenmiş tüketici kurallarını yerel saklama kuralları dosyanıza kopyalayın, paketlenmiş kuralları Hatalı saklama kurallarını filtreleme bölümünde gösterildiği gibi filtreleyin ve kopyalanan kuralları daraltın. Uygulamanızın küçültme, optimizasyon ve kod karartma puanlarını karşılaştırmak için kuralları daraltmadan önce ve sonra R8 Yapılandırma Analiz Aracı'nı çalıştırın.
  3. Bulguları bildirin: R8 Configuration Analyzer raporunuzdaki deneysel verileri içeren bir hata raporunu kitaplık sorumlusuna gönderin (örneğin, joker karakter kuralı tarafından korunan, referans verilmeyen sınıfların veya yöntemlerin sayısını gösterin).

Örnek olay: Gson neden optimizasyonlarla bozulur?

Gson, yoğun bir şekilde yansıma kullandığı için genellikle uygulama optimizasyonuyla ilgili sorunlara neden olan bir serileştirme kitaplığıdır. Aşağıdaki kod snippet'inde, Gson'un genellikle nasıl kullanıldığı gösterilmektedir. Bu kullanım, çalışma zamanında kilitlenmelere neden olabilir. Gson'u kullanarak User nesnelerinin listesini aldığınızda, kurucuyu çağırmadığınıza veya fromJson() işlevine bir fabrika iletmediğinize dikkat edin. Aşağıdakilerden biri olmadan uygulama tarafından tanımlanan sınıfları oluşturmak veya kullanmak, bir kitaplığın ucu açık yansıma kullandığının işaretidir:

  • Bir kitaplığı, standart arayüzü veya sınıfı uygulayan uygulama sınıfı
  • KSP gibi kod oluşturma eklentisi
class User(val name: String)
class UserList(val users: List<User>)

// This code runs in debug mode, but crashes when optimizations are enabled
Gson().fromJson("""[{"name":"myname"}]""", User::class.java).toString()

R8'in Gson'da nasıl çalıştığını anlamak için Gson tüketici kuralları'na bakın. R8 bu kodu analiz ettiğinde UserList veya User öğelerinin hiçbir yerde örneklendirilmediğini görürse alanları yeniden adlandırabilir veya kullanılmadığı görülen kurucuları kaldırarak uygulamanızın kilitlenmesine neden olabilir. Benzer şekilde başka kitaplıklar kullanıyorsanız bunların uygulama optimizasyonunu engellemediğinden emin olmanız ve engelliyorlarsa bunları kullanmamanız gerekir.

@SerializedName özelliğini daha sonraki Gson sürümleriyle kullanma

Veri modellerinizi Gson'un tüketici kurallarıyla uyumlu bir şekilde tanımlamak için alanlarınıza @SerializedName ile ek açıklama ekleyin. Aşağıdaki snippet'te bunun nasıl yapılacağı gösterilmektedir:

import com.google.gson.annotations.SerializedName

class User(@SerializedName("name") val name: String)
class UserList(@SerializedName("users") val users: List<User>)

@SerializedName ek açıklamasını kullanarak R8'in, model sınıflarınızı Gson 2.11.0 ve sonraki sürümlerde bulunan saklama kurallarıyla eşleştirmesine izin verirsiniz. R8, ek açıklamalı alanları ve gerekli kurucuları otomatik olarak korur. Böylece projenizde manuel ProGuard yapılandırmaları yapmanıza gerek kalmadan kitaplığın paketlenmiş kurallarını kullanabilirsiniz.

Room, Hilt ve codegen ile Moshi'nin uygulama tarafından tanımlanan türler oluşturduğunu ancak yansıtma ihtiyacını önlemek için codegen kullandığını unutmayın.