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 bir değişiklik 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 son haline getirilmediğinden 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.

Yansıtmanın uygun olduğu durumlar

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ı kullanarak kodlama

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 (örneğin, etkinlikler, görünümler ve çizilebilir öğeler şişirilirken) hem de AndroidX kitaplıklarında (örneğin, 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ı türde saklama kuralı 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 veya 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ı engellemeleri gerekir. 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 için AAR kitaplığı derlemesini optimize etme başlıklı makaleyi inceleyin.

Tüketici saklama kuralları yazma

Genel saklama kuralı yönergelerinin yanı sıra, özellikle kitaplık yazarları için aşağıdaki öneriler geçerlidir.

  • 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.
  • 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ı tüketen uygulamalar optimize edilmemiş olsa bile kitaplığınızı daha verimli hale getirebilir ancak uygulamalar da optimize edildiğ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 beyan edin.
  • Kitaplık dağıtımınızda 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 rehberimizi inceleyin.

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 kural 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 bilebilir. Kitaplık geliştiricisi olarak, kitaplığı optimize etmeden önce optimizasyonun birden fazla aşamasını göz önünde bulundurmanız ve 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 kullanılarak kitaplığınızın hangi bölümünün kitaplık oluşturma sırasında korunacağını tanımlar. Bu, en azından herkese açık API'nizdir.
  • consumerProguardFiles ise kitaplığınızın derlenmesi sırasında daha sonra hangi optimizasyonların yapılacağını 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 eski R8 sürümlerinin kullanıldığı projelerde de 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 bulunabilir. Bu dosyalar herhangi bir ada ve uzantıya sahip 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, bir dizi hedeflenen R8 kuralını 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, R8 tarafından 8.0.0 sürümünden 8.2.0 sürümüne kadar (8.2.0 dahil değil) 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.