Kitaplık yazarları için optimizasyon

Kitaplık yazarı olarak, uygulama geliştiricilerin kitaplığınızı uygulamalarına kolayca dahil edebilmesini ve yüksek kaliteli bir son kullanıcı deneyimi sunabilmesini sağlamanız gerekir. Kitaplığınızın ek kurulum olmadan Android optimizasyonuyla uyumlu olduğundan emin olmanız veya kitaplığın Android'de kullanıma uygun olmayabileceğini belgelemeniz gerekir.

Bu doküman, yayınlanmış kitaplıkların geliştiricilerine yöneliktir ancak büyük ve modüler bir uygulamadaki dahili kitaplık modüllerinin geliştiricileri için de faydalı olabilir.

Uygulama geliştiriciyseniz ve Android uygulamanızı optimize etme hakkında bilgi edinmek istiyorsanız Uygulama optimizasyonunu etkinleştirme başlıklı makaleyi inceleyin. Hangi kitaplıkların kullanıma uygun olduğu hakkında bilgi edinmek için Kitaplıkları akıllıca seçme başlıklı makaleyi inceleyin.

Yansıtma yerine kod oluşturmayı kullanma

Mümkün olduğunda yansıtma yerine kod oluşturmayı (codegen) kullanın. Codegen ve yansıtma, programlama sırasında standart koddan kaçınmak için kullanılan yaygın yaklaşımlardır. Ancak codegen, R8 gibi bir uygulama optimize ediciyle daha uyumludur:

  • Kod oluşturma ile kod, derleme işlemi sırasında analiz edilir ve değiştirilir. Derleme zamanından sonra büyük değişiklikler yapılmadığından, optimize edici hangi kodun nihai olarak gerekli olduğunu ve hangisinin güvenli bir şekilde kaldırılabileceğini bilir.
  • Yansıtma ile kod, çalışma zamanında analiz edilir ve üzerinde değişiklik yapılır. Kod yürütülene kadar gerçekten sonlandırılmadığından, optimize edici hangi kodun güvenli bir şekilde kaldırılabileceğini bilemez. Bu işlem, çalışma zamanında yansıtma yoluyla dinamik olarak kullanılan kodu kaldırdığı için kullanıcılar uygulamada kilitlenme sorunu yaşayabilir.

Birçok modern kitaplık, yansıtma yerine kod oluşturma kullanır. Room, Dagger2 ve diğer birçok kitaplık tarafından kullanılan ortak bir giriş noktası için KSP'ye bakın.

Ne zaman yansıtma yapılabilir?

Yansıtma kullanmanız gerekiyorsa yalnızca aşağıdakilerden birine yansıtma yapmalısınız:

  • Belirli hedeflenen türler (belirli arayüz uygulayıcıları veya alt sınıflar)
  • Belirli bir çalışma zamanı ek açıklaması kullanan kod

Yansıtmayı bu şekilde kullanmak, çalışma zamanı maliyetini sınırlar ve hedefli tüketici saklama kuralları yazmaya olanak tanır.

Bu özel ve hedeflenmiş yansıtma biçimi, hem Android çerçevesinde (ör. etkinlikler, görünümler ve çizilebilir öğeler genişletilirken) hem de AndroidX kitaplıklarında (ör. WorkManager ListenableWorkers veya RoomDatabases oluşturulurken) görebileceğiniz bir kalıptır. Buna karşılık, Gson'un açık uçlu yansıtması Android uygulamalarında kullanıma uygun değildir.

Kitaplıklardaki saklama kuralı türleri

Kitaplıklarda kullanabileceğiniz iki farklı saklama kuralı türü vardır:

  • Tüketici saklama kuralları, kitaplığın yansıttığı her şeyi saklayan kuralları belirtmelidir. Bir kitaplık, kodunu veya bir istemci uygulaması tarafından tanımlanan kodu çağırmak için yansıtma ya da JNI kullanıyorsa bu kurallarda hangi kodun korunması gerektiği açıklanmalıdır. Kitaplıklar, uygulama saklama kurallarıyla aynı biçimi kullanan tüketici saklama kurallarını paketlemelidir. Bu kurallar, kitaplık yapılarına (AAR veya JAR) paketlenir ve kitaplık kullanıldığında Android uygulaması optimizasyonu sırasında otomatik olarak tüketilir. Bu kurallar, build.gradle.kts (veya build.gradle) dosyanızda consumerProguardFiles özelliğiyle belirtilen dosyada tutulur. Daha fazla bilgi için Tüketici saklama kuralları yazma başlıklı makaleyi inceleyin.
  • Kitaplık oluşturma saklama kuralları, kitaplığınız oluşturulurken uygulanır. Bu dosyalar yalnızca kitaplığınızı derleme sırasında kısmen optimize etmeye karar verirseniz gereklidir. Kitaplığın herkese açık API'sinin kaldırılmasını önlemelidirler. Aksi takdirde, herkese açık API kitaplık dağıtımında yer almaz ve uygulama geliştiriciler kitaplığı kullanamaz. Bu kurallar, build.gradle.kts (veya build.gradle) dosyanızda proguardFiles özelliğiyle belirtilen dosyada tutulur. Daha fazla bilgi edinmek için AAR kitaplığı derlemesini optimize etme başlıklı makaleyi inceleyin.

Tüketici saklama kuralları yazma

Genel saklama kuralı en iyi uygulamalarının yanı sıra, özellikle kitaplık yazarları için aşağıdaki önerilerde bulunuyoruz.

  • Uygunsuz genel kurallar kullanmayın. Kitaplığınızı kullanan tüm uygulamaları etkilediği için kitaplığınızın tüketiciye yönelik saklama kuralları dosyasına -dontobfuscate veya -allowaccessmodification gibi genel ayarlar eklemeyin.
  • -keep class com.mylibrary.** { *; } gibi paket genelinde saklama kurallarını eklemeyin. Bu tür kurallar, kitaplığın tamamında optimizasyonu sınırlandırarak kitaplığı kullanan tüm uygulamaların boyutunu etkiler.
  • Kitaplığınızın tüketici saklama kuralları dosyasında -repackageclasses kullanmayın. Ancak kitaplık derlemenizi optimize etmek için kitaplığınızın derleme kurallarını koruma dosyasında -repackageclasses gibi dahili bir paket adıyla <your.library.package>.internal kullanabilirsiniz. Bu, kitaplığınızı kullanan uygulamalar optimize edilmemiş olsa bile kitaplığınızı daha verimli hale getirebilir ancak uygulamaların da optimize edilmesi gerektiğinden genellikle gerekli değildir. Kitaplıkları optimize etme hakkında daha fazla bilgi için Kitaplık yazarları için optimizasyon başlıklı makaleyi inceleyin.
  • Kitaplığınızın çalışması için gereken tüm özellikleri, proguard-android-optimize.txt içinde tanımlanan özelliklerle çakışma olsa bile kitaplığınızın saklama kuralları dosyalarında bildirin.
  • Kitaplığınızın dağıtımında aşağıdaki özelliklerin bulunmasını zorunlu kılıyorsanız bunları kitaplığınızın derleme koruma kuralları dosyasında tutun ve kitaplığınızın tüketici koruma kuralları dosyasında tutmayın:
    • AnnotationDefault
    • EnclosingMethod
    • Exceptions
    • InnerClasses
    • RuntimeInvisibleAnnotations
    • RuntimeInvisibleParameterAnnotations
    • RuntimeInvisibleTypeAnnotations
    • RuntimeVisibleAnnotations
    • RuntimeVisibleParameterAnnotations
    • RuntimeVisibleTypeAnnotations
    • Signature
  • Kitaplık yazarları, çalışma zamanında ek açıklamalar kullanılıyorsa tüketici saklama kurallarında RuntimeVisibleAnnotations özelliğini tutmalıdır.
  • Kitaplık yazarları, tüketici saklama kurallarında aşağıdaki genel seçenekleri kullanmamalıdır:
    • -include
    • -basedirectory
    • -injars
    • -outjars
    • -libraryjars
    • -repackageclasses
    • -flattenpackagehierarchy
    • -allowaccessmodification
    • -overloadaggressively
    • -renamesourcefileattribute
    • -ignorewarnings
    • -addconfigurationdebugging
    • -printconfiguration
    • -printmapping
    • -printusage
    • -printseeds
    • -applymapping
    • -obfuscationdictionary
    • -classobfuscationdictionary
    • -packageobfuscationdictionary

AAR kitaplıkları

AAR kitaplığı için tüketici kuralları eklemek üzere Android kitaplığı modülünün derleme komut dosyasında consumerProguardFiles seçeneğini kullanın. Daha fazla bilgi için kitaplık modülü oluşturma rehberimize göz atın.

Kotlin

android {
    defaultConfig {
        consumerProguardFiles("consumer-proguard-rules.pro")
    }
    ...
}

Groovy

android {
    defaultConfig {
        consumerProguardFiles 'consumer-proguard-rules.pro'
    }
    ...
}

JAR kitaplıkları

Kuralları, JAR olarak gönderilen Kotlin/Java kitaplığınızla birlikte paketlemek için kurallar dosyanızı nihai JAR'ın META-INF/proguard/ dizinine herhangi bir dosya adıyla yerleştirin. Örneğin, kodunuz <libraryroot>/src/main/kotlin konumundaysa <libraryroot>/src/main/resources/META-INF/proguard/consumer-proguard-rules.pro konumuna bir tüketici kuralları dosyası yerleştirin. Kurallar, çıkış JAR'ınızda doğru konuma yerleştirilir.

Kuralların META-INF/proguard dizininde olduğunu kontrol ederek nihai JAR paketlerinin kuralları doğru şekilde paketlediğini doğrulayın.

AAR kitaplığı derlemesini optimize etme (gelişmiş)

Genellikle, kitaplık oluşturma sırasında olası optimizasyonlar çok sınırlı olduğundan kitaplık derlemesini doğrudan optimize etmeniz gerekmez. R8, yalnızca bir kitaplık uygulamaya dahil edildiğinde, uygulama derleme sırasında kitaplığın tüm yöntemlerinin nasıl kullanıldığını ve hangi parametrelerin iletildiğini öğrenebilir. Kitaplık geliştiricisi olarak, optimizasyonun birden fazla aşamasını göz önünde bulundurmanız ve kitaplığı optimize etmeden önce hem kitaplık hem de uygulama derleme zamanında davranışları korumanız gerekir.

Kitaplığınızı derleme sırasında optimize etmek istiyorsanız bu işlem Android Gradle eklentisi tarafından desteklenir.

Kotlin

android {
    buildTypes {
        release {
            isMinifyEnabled = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
        configureEach {
            consumerProguardFiles("consumer-rules.pro")
        }
    }
}

Groovy

android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles
                getDefaultProguardFile('proguard-android-optimize.txt'),
                'proguard-rules.pro'
        }
        configureEach {
            consumerProguardFiles "consumer-rules.pro"
        }
    }
}

proguardFiles davranışının consumerProguardFiles davranışından çok farklı olduğunu unutmayın:

  • proguardFiles, kitaplık oluşturma sırasında, genellikle getDefaultProguardFile("proguard-android-optimize.txt") ile birlikte, kitaplığınızın hangi bölümünün kitaplık oluşturma sırasında korunacağını tanımlamak için kullanılır. En azından bu, herkese açık API'nizdir.
  • consumerProguardFiles ise kitaplığınızı kullanan bir uygulamanın derlenmesi sırasında daha sonra yapılacak optimizasyonları etkilemek için kitaplığa paketlenir.

Örneğin, kitaplığınız dahili sınıfları oluşturmak için yansıtma kullanıyorsa hem proguardFiles hem de consumerProguardFiles içinde koruma kurallarını tanımlamanız gerekebilir.

Kitaplığınızın derlemesinde -repackageclasses kullanıyorsanız sınıfları kitaplığınızın paketinin içinde bir alt pakete yeniden paketleyin. Örneğin, -repackageclasses 'internal' yerine -repackageclasses 'com.example.mylibrary.internal' kullanın.

Farklı R8 sürümlerini destekleme (gelişmiş)

Kuralları, R8'in belirli sürümlerini hedefleyecek şekilde uyarlayabilirsiniz. Bu sayede, kitaplığınız daha yeni R8 sürümlerinin kullanıldığı projelerde optimum şekilde çalışırken mevcut kurallar, daha eski R8 sürümlerinin kullanıldığı projelerde kullanılmaya devam edebilir.

Hedeflenen R8 kurallarını belirtmek için bunları AAR'nin classes.jar içindeki META-INF/com.android.tools dizinine veya JAR'ın META-INF/com.android.tools dizinine eklemeniz gerekir.

In an AAR library:
    proguard.txt (legacy location, the file name must be "proguard.txt")
    classes.jar
    └── META-INF
        └── com.android.tools (location of targeted R8 rules)
            ├── r8-from-<X>-upto-<Y>/<R8-rule-files>
            └── ... (more directories with the same name format)

In a JAR library:
    META-INF
    ├── proguard/<ProGuard-rule-files> (legacy location)
    └── com.android.tools (location of targeted R8 rules)
        ├── r8-from-<X>-upto-<Y>/<R8-rule-files>
        └── ... (more directories with the same name format)

META-INF/com.android.tools dizininde, kuralların hangi R8 sürümleri için yazıldığını belirtmek üzere r8-from-<X>-upto-<Y> biçiminde adlara sahip birden fazla alt dizin olabilir. Her alt dizinde, R8 kurallarını içeren bir veya daha fazla dosya olabilir. Dosya adları ve uzantıları herhangi bir şekilde olabilir.

-from-<X> ve -upto-<Y> bölümlerinin isteğe bağlı olduğunu, <Y> sürümünün özel olduğunu ve sürüm aralıklarının genellikle kesintisiz olduğunu ancak çakışabileceğini unutmayın.

Örneğin, r8, r8-upto-8.0.0, r8-from-8.0.0-upto-8.2.0 ve r8-from-8.2.0, hedeflenen bir R8 kuralı grubunu temsil eden dizin adlarıdır. r8 dizinindeki kurallar, tüm R8 sürümleri tarafından kullanılabilir. r8-from-8.0.0-upto-8.2.0 dizinindeki kurallar, 8.0.0 sürümünden 8.2.0 sürümüne kadar (8.2.0 dahil değil) R8 tarafından kullanılabilir.

Android Gradle eklentisi, mevcut R8 sürümü tarafından kullanılabilecek tüm kuralları seçmek için bu bilgileri kullanır. Bir kitaplık, hedeflenen R8 kurallarını belirtmezse Android Gradle eklentisi, kuralları eski konumlardan (AAR için proguard.txt veya JAR için META-INF/proguard/<ProGuard-rule-files>) seçer.