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 (ör. ilişkili keep kurallarını paketlemeden yansıtma 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 ipuçları

Kitaplıklarınızın uygulama optimizasyonuyla uyumlu olduğundan emin olmak için bu ipuçlarından yararlanın.

Yansıtma yerine kod oluşturmayı tercih etme

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

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

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

Bir kitaplığın yansıtma kullanıp kullanmadığını kodunu inceleyerek anlayabilirsiniz. Kitaplık yansıtma kullanıyorsa ilişkili saklama kuralları sağladığını kontrol edin. Bir kitaplık, aşağıdakileri yapıyorsa yansıtma kullanıyor olabilir:

  • 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 saklar ve ardından value ile bir işlem yapar.
  • Aşağıdaki örnekte olduğu gibi, yöntem adını dize olarak kullanarak yöntemleri çağırır:

    // 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ığı değerlendirirken küçültme veya uygulama optimizasyonunu yapılandırmayla ilgili sorunlar olup olmadığını kontrol etmek için kitaplığın sorun izleyicisine ve online tartışmalara göz atın. Bu durumda, söz konusu kitaplığa alternatifler aramayı deneyebilirsiniz. Aşağıdakileri göz önünde bulundurun:

  • AndroidX kitaplıkları ve Hilt gibi kitaplıklar, yansıtma yerine çoğunlukla kod oluşturma kullandıkları için uygulama optimizasyonuyla iyi çalışır. Yansıtma kullandıklarında ise yalnızca gereken kodu tutmak için minimum tutma kuralları sağlarlar.
  • Serileştirme kitaplıkları, nesneleri oluştururken veya serileştirirken ortak metin kodundan kaçınmak için genellikle yansıtma kullanır. Yansımaya dayalı yaklaşımlar (ör. JSON için Gson) 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 koruma kuralları içeren kitaplıklardan kaçının. Paket genelinde saklama kuralları hataların çözülmesine yardımcı olabilir ancak geniş kapsamlı saklama kuralları, yalnızca gerekli kodu saklayacak şekilde iyileştirilmelidir. Daha fazla bilgi için Optimizasyonları kademeli olarak uygulama başlıklı makaleyi inceleyin.
  • Kitaplıklar, özellikle paket genelinde tutma kuralları olmak üzere, dokümanlardaki tutma kurallarını projenizdeki bir dosyaya kopyalayıp yapıştırmanızı gerektirmemelidir. Bu kurallar, uzun vadede uygulama geliştiricinin bakım yükünü artırır ve zaman içinde optimize edilip değiştirilmesi zorlaşır.

Yeni bir kitaplık ekledikten sonra optimizasyonu etkinleştirme

Yeni bir kitaplık eklediğinizde optimizasyonu daha sonra etkinleştirin ve hata olup olmadığını kontrol edin. Hata varsa bu kitaplığa alternatifler arayın veya saklama kuralları yazın. Bir kitaplık optimizasyonla uyumlu değilse bu kitaplıkla ilgili bir hata bildirimi gönderin.

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

Saklama kuralları eklemelidir. 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ık kod optimizasyonlarını devre dışı bırakma kuralı içeriyorsa bu kural, projenizin tamamında optimizasyonları devre dışı bırakır.

Gerçekten kaldırılması gereken kodu koruyan kurallara sahip kitaplıklardan kaçınmalısınız. Ancak bunları kullanmanız gerekiyorsa aşağıdaki kodda gösterildiği gibi kuralları 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")
        }
    }
}

Örnek olay: Gson neden optimizasyonlarla uyumlu değil?

Gson, yansıtmayı yoğun bir şekilde 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 durum, çalışma zamanında kolayca kilitlenmelere neden olabilir. Gson'ı kullanarak User nesnelerinin listesini aldığınızda oluşturucuyu çağırmadığınızı veya fromJson() işlevine fabrika geçirmediğinizi unutmayın. Aşağıdakilerden hiçbiri olmadan uygulama tanımlı sınıfların oluşturulması veya kullanılması, bir kitaplığın açık uçlu yansıtma kullanıyor olabileceğinin işaretidir:

  • Kitaplık, 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ı bölümüne bakın. R8 bu kodu analiz ettiğinde UserList veya User öğesinin hiçbir yerde oluşturulmadığını görürse alanları yeniden adlandırabilir ya da kullanılmıyor gibi görünen oluşturucuları kaldırabilir. Bu durum, uygulamanızın kilitlenmesine neden olur. Benzer şekilde başka kitaplıklar kullanıyorsanız bunların uygulama optimizasyonunu engellemediğinden emin olmanız ve engelliyorsa bu kitaplıkları kullanmamanız gerekir.

Sınıfları Gson'un tüketici kurallarıyla uyumlu şekilde tanımlamak için aşağıdaki snippet'i referans olarak kullanın:

class User(@com.google.gson.annotations.SerializedName("name") val name: String)
class UserList(@com.google.gson.annotations.SerializedName("users") val users: List<User>)

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