Android Gradle eklentisi (AGP), Android uygulamaları için resmi derleme sistemidir. Birçok farklı kaynak türünü derleme ve bunları fiziksel bir Android cihazda veya emülatörde çalıştırabileceğiniz bir uygulamaya bağlama desteği içerir.
AGP, eklentilerin derleme girişlerini kontrol etmesi ve standart derleme görevleriyle entegre edilebilecek yeni adımlar aracılığıyla işlevlerini genişletmesi için uzantı noktaları içerir. AGP'nin önceki sürümlerinde, dahili uygulamalardan net bir şekilde ayrılmış resmi API'ler yoktu. 7.0 sürümünden itibaren AGP, güvenebileceğiniz bir dizi resmi ve kararlı API içerir.
AGP API yaşam döngüsü
AGP, API'lerinin durumunu belirlemek için Gradle özellik yaşam döngüsünü izler:
- Dahili: Herkese açık kullanıma yönelik değildir.
- Kuluçka: Herkese açık olarak kullanılabilir ancak nihai sürüm değildir. Bu nedenle, nihai sürümde geriye dönük uyumlu olmayabilir.
- Herkese açık: Herkesin kullanımına açık ve kararlı
- Desteği sonlandırıldı: Artık desteklenmiyor ve yeni API'lerle değiştirildi.
Kullanımdan kaldırma politikası
AGP, eski API'lerin kullanımdan kaldırılması ve bunların yerine yeni, kararlı API'lerin ve yeni bir alana özgü dilin (DSL) kullanılmasıyla gelişiyor. Bu gelişim birden fazla AGP sürümünü kapsayacak. Bu konuda daha fazla bilgiyi AGP API/DSL taşıma zaman çizelgesinde bulabilirsiniz.
AGP API'leri bu taşıma işlemi için veya başka bir nedenle kullanımdan kaldırıldığında mevcut ana sürümde kullanılmaya devam eder ancak uyarılar oluşturur. Desteği sonlandırılan API'ler, bir sonraki ana sürümde AGP'den tamamen kaldırılacaktır. Örneğin, AGP 7.0'da desteği sonlandırılan bir API, bu sürümde kullanılabilir ve uyarılar oluşturur. Bu API, AGP 8.0'da artık kullanılamayacak.
Yaygın derleme özelleştirmelerinde kullanılan yeni API'lerin örneklerini görmek için Android Gradle eklentisi tariflerine göz atın. Yaygın derleme özelleştirmeleriyle ilgili örnekler sunar. Yeni API'ler hakkında daha fazla bilgiyi referans belgelerimizde bulabilirsiniz.
AGP API yapısına göre derleme
AGP'yi genişleten özel bir Gradle eklentisi veya derleme mantığı (ör. buildSrc dizininde, kural eklenti modülünde veya bağımsız bir eklenti projesinde) yazmak için tam eklenti uygulama yapısı yerine AGP'nin gradle-api yapısına göre derleyin.
Neden gradle-api yapısına karşı derleme yapmalısınız?
AGP iki ana yapı yayınlar:
com.android.tools.build:gradle-api: Kararlı API'ler (ör.AndroidComponentsExtension,Variantve herkese açık DSL arayüzleri), kuluçka aşamasındaki API'ler (@Incubatingile işaretli) ve desteği sonlandırılmış API'ler (@Deprecatedile işaretli) dahil olmak üzere resmi AGP API'lerini içerir.com.android.tools.build:gradle: Dahili sınıflar, derleme görevleri ve derleyici entegrasyonları dahil olmak üzere tam AGP çalışma zamanı uygulamasını içerir.
gradle-api yapısına karşı derleme yapmanın birkaç önemli avantajı vardır:
- Dahili API'lerden kaçınma: Eklenti kodunuzun yalnızca resmi API'lere erişmesini sağlar. Bu sayede, AGP sürümleri arasında uyarı yapılmadan değiştirilebilen veya kaldırılabilen dahili uygulama sınıflarına (
com.android.build.gradle.internal.*) yanlışlıkla bağımlılık oluşturulması önlenir. - Daha hızlı derlemeler ve daha küçük ayak izi:
gradle-apiyapısı, tamgradleyapısına kıyasla çok daha küçük bir bağımlılık ağacına sahiptir. Bu sayede indirme boyutları küçülür, sınıf yolu kirliliği önlenir ve derleme mantığınızın derlenmesi hızlanır. - Çalışma zamanı izolasyonu: Özel eklentiler, derleme sırasında yalnızca API tanımları gerektirir. Çalışma zamanında, Android uygulaması veya kitaplık eklentisi uygulandığında tam AGP uygulaması Android derlemesi tarafından sağlanır.
Bağımlılığı ekleme
gradle-api yapısını, eklenti projenizin derleme dosyasına veya buildSrc dizinine bağımlılık olarak ekleyin. gradle-api yapısı, Google'ın Maven deposunda yayınlanır. Yapı sorununu çözmek için derlemenizin google() deposunu içerdiğinden emin olun. Örneğin, settings.gradle veya settings.gradle.kts dosyasının dependencyResolutionManagement.repositories bloğunda ya da eklentinizin derleme dosyasının repositories bloğunda veya buildSrc dizininin derleme dosyasında yapılandırın.
Sürüm kataloğu ile
Projeniz sürüm kataloğu kullanıyorsa gradle/libs.versions.toml dosyasında gradle-api bağımlılığını tanımlayın:
[versions]
androidGradlePlugin = "9.4.0"
[libraries]
android-gradle-plugin-api = { group = "com.android.tools.build", name = "gradle-api", version.ref = "androidGradlePlugin" }
android-gradle-plugin-api katalog takma adı, tip güvenli erişimciyi oluşturur
libs.android.gradle.plugin.api.
Ardından, eklentinizin derleme dosyasının dependencies bloğuna libs.android.gradle.plugin.api öğesini ekleyin:
Kotlin
dependencies { compileOnly(libs.android.gradle.plugin.api) }
Modern
dependencies { compileOnly libs.android.gradle.plugin.api }
Sürüm kataloğu olmadan
Projeniz sürüm kataloğu kullanmıyorsa bağımlılığı doğrudan eklentinizin derleme dosyasında bildirin:
Kotlin
dependencies { compileOnly("com.android.tools.build:gradle-api:9.4.0") }
Modern
dependencies { compileOnly 'com.android.tools.build:gradle-api:9.4.0' }
Yayınlanması amaçlanan bağımsız eklentiler için varsayılan olarak compileOnly yapılandırma seçeneğini kullanın. Tüketen proje, AGP'yi uygular ve çalışma zamanı sınıflarını buildscript sınıf yolunda sağlar. compileOnly yapılandırmasını kullanmak, yayınlanan eklentinizin belirli bir AGP sürümünde çalışma zamanı bağımlılığını sızdırmasını ve tüketiciler için sürüm çakışmalarını önler. Dahili derleme mantığı (ör. buildSrc dizinindeki eklentiler veya bileşik derlemelerdeki kural eklentileri) geliştiriyorsanız bunun yerine implementation yapılandırma seçeneğini kullanın. Bu eklentiler derleme içinde çalışır ve çalışma zamanı sınıf yolunda AGP gerektirir.
Gradle derleme ile ilgili temel bilgiler
Bu kılavuz, Gradle derleme sisteminin tamamını kapsamaz. Ancak API'lerimizle entegrasyon yapmanıza yardımcı olacak minimum gerekli kavramları kapsar ve daha fazla bilgi için ana Gradle belgelerine bağlantı verir.
Projeleri yapılandırma, derleme dosyalarını düzenleme, eklenti uygulama ve görevleri çalıştırma gibi Gradle'ın işleyiş şekliyle ilgili temel bilgilere sahip olduğunuzu varsayıyoruz. AGP ile ilgili olarak Gradle'ın temel özellikleri hakkında bilgi edinmek için Derlemenizi yapılandırma başlıklı makaleyi incelemenizi öneririz. Gradle eklentilerini özelleştirmeyle ilgili genel çerçeve hakkında bilgi edinmek için Özel Gradle Eklentileri Geliştirme başlıklı makaleyi inceleyin.
Gradle geç yüklenen türler sözlüğü
Gradle,"tembel" davranan veya ağır hesaplamaları ya da Task oluşturma işlemlerini derlemenin sonraki aşamalarına ertelemeye yardımcı olan çeşitli türler sunar. Bu türler, birçok Gradle ve AGP API'sinin temelini oluşturur. Aşağıdaki listede, geç yürütme işleminde yer alan ana Gradle türleri ve bunların temel yöntemleri yer almaktadır.
Provider<T>- Yürütme aşamasında
get()kullanılarak okunabilen veyamap(),flatMap()vezip()yöntemleri kullanılarak yeni birProvider<S>("S" başka bir türü ifade eder) değerine dönüştürülebilenTtüründe ("T" herhangi bir türü ifade eder) bir değer sağlar.get(), yapılandırma aşamasında hiçbir zaman çağrılmamalıdır.map(): Lambda kabul eder veS,Provider<S>türünde birProvideroluşturur.map()işlevinin lambda bağımsız değişkeni,Tdeğerini alır veSdeğerini üretir. Lambda hemen yürütülmez. Bunun yerine, yürütme işlemi sonuçta elde edilenProvider<S>üzerindeget()çağrıldığı ana ertelenir. Bu da tüm zinciri geçici hale getirir.flatMap(): Ayrıca bir lambda kabul eder veProvider<S>üretir ancak lambda,Tdeğerini alır veProvider<S>üretir (doğrudanSdeğerini üretmek yerine). S, yapılandırma sırasında belirlenemediğinde ve yalnızcaProvider<S>elde edebildiğinizde flatMap() işlevini kullanın. Pratik olarak,map()kullandıysanız ve sonuç türüProvider<Provider<S>>olduysa bu, muhtemelen bunun yerineflatMap()kullanmanız gerektiği anlamına gelir.zip(): İkiProviderörneğini birleştirerek yeni birProvideroluşturmanızı sağlar. Bu yeni örneğin değeri, iki girişProvidersörneğindeki değerleri birleştiren bir işlev kullanılarak hesaplanır.
Property<T>- ,
Provider<T>uygulamasını kullanır. Bu nedenleTtüründe bir değer de sağlar. Salt okunur olanProvider<T>parametresinin aksine,Property<T>parametresi için bir değer de ayarlayabilirsiniz. Bunu yapmanın iki yolu vardır:- Mümkün olduğunda, ertelenmiş hesaplamalara gerek kalmadan doğrudan
Ttüründe bir değer ayarlayın. Property<T>değerinin kaynağı olarak başka birProvider<T>ayarlayın. Bu durumdaTdeğeri yalnızcaProperty.get()çağrıldığında somutlaştırılır.
- Mümkün olduğunda, ertelenmiş hesaplamalara gerek kalmadan doğrudan
TaskProvider- Uygulama
Provider<Task>.TaskProvideroluşturmak içintasks.create()yerinetasks.register()kullanın. Böylece görevler yalnızca gerektiğinde örneklendirilir.flatMap()kullanarak birTaskTaskoluşturulmadan önce çıkışlarına erişebilirsiniz. Bu, çıkışları diğerTaskörneklerine giriş olarak kullanmak istediğinizde yararlı olabilir.
Sağlayıcılar ve bunların dönüştürme yöntemleri, görevlerin giriş ve çıkışlarını geç bir şekilde ayarlamak için gereklidir. Yani tüm görevleri önceden oluşturup değerleri çözmeye gerek yoktur.
Sağlayıcılar, görev bağımlılığı bilgilerini de taşır. Bir Task çıkışını dönüştürerek Provider oluşturduğunuzda bu Task, Provider için dolaylı bir bağımlılık hâline gelir ve Provider değeri çözümlendiğinde (ör. başka bir Task bunu gerektirdiğinde) oluşturulup çalıştırılır.
Aşağıda, GitVersionTask ve ManifestProducerTask olmak üzere iki görevin kaydedilmesine ve Task örneklerinin oluşturulmasının gerçekten gerekli olana kadar ertelenmesine dair bir örnek verilmiştir. ManifestProducerTask giriş değeri, GitVersionTask çıkışından elde edilen bir Provider değerine ayarlanır. Bu nedenle ManifestProducerTask, dolaylı olarak GitVersionTask değerine bağlıdır.
// Register a task lazily to get its TaskProvider.
val gitVersionProvider: TaskProvider =
project.tasks.register("gitVersionProvider", GitVersionTask::class.java) {
it.gitVersionOutputFile.set(
File(project.buildDir, "intermediates/gitVersionProvider/output")
)
}
...
/**
* Register another task in the configuration block (also executed lazily,
* only if the task is required).
*/
val manifestProducer =
project.tasks.register(variant.name + "ManifestProducer", ManifestProducerTask::class.java) {
/**
* Connect this task's input (gitInfoFile) to the output of
* gitVersionProvider.
*/
it.gitInfoFile.set(gitVersionProvider.flatMap(GitVersionTask::gitVersionOutputFile))
}
Bu iki görev yalnızca açıkça istendiğinde yürütülür. Bu durum, Gradle çağrısının bir parçası olarak gerçekleşebilir. Örneğin, ./gradlew
debugManifestProducer komutunu çalıştırırsanız veya ManifestProducerTask çıkışı başka bir göreve bağlanırsa ve değeri gerekli hale gelirse bu durum yaşanabilir.
Girişleri kullanan ve/veya çıkışlar üreten özel görevler yazacak olsanız da AGP, kendi görevlerine doğrudan herkese açık erişim sunmaz. Bunlar, sürümler arasında değişebilen bir uygulama ayrıntısıdır. Bunun yerine AGP, Variant API'yi ve okuyup dönüştürebileceğiniz görevlerinin çıktısına veya derleme yapılarına erişim imkanı sunar. Daha fazla bilgi için bu dokümandaki Variant API, Artifacts, and Tasks (Variant API, Yapılar ve Görevler) bölümüne bakın.
Gradle derleme aşamaları
Proje oluşturmak doğası gereği karmaşık ve kaynak gerektiren bir süreçtir. Görev yapılandırmasından kaçınma, güncel kontroller ve yapılandırma önbelleğe alma gibi çeşitli özellikler, tekrarlanabilir veya gereksiz hesaplamalara harcanan süreyi en aza indirmeye yardımcı olur.
Bu optimizasyonlardan bazılarını uygulamak için Gradle komut dosyaları ve eklentileri, farklı Gradle derleme aşamalarının her birinde (başlatma, yapılandırma ve yürütme) katı kurallara uymalıdır. Bu kılavuzda, yapılandırma ve yürütme aşamalarına odaklanacağız. Tüm aşamalar hakkında daha fazla bilgiyi Gradle derleme yaşam döngüsü kılavuzunda bulabilirsiniz.
Yapılandırma aşaması
Yapılandırma aşamasında, derlemenin parçası olan tüm projelerin derleme komut dosyaları değerlendirilir, eklentiler uygulanır ve derleme bağımlılıkları çözümlenir. Bu aşama, DSL nesnelerini kullanarak derlemeyi yapılandırmak ve görevleri ve girişlerini geç kaydetmek için kullanılmalıdır.
Yapılandırma aşaması, hangi görevin çalıştırılması istendiğine bakılmaksızın her zaman çalıştırılır. Bu nedenle, bu aşamayı yalın tutmak ve hesaplamaların derleme komut dosyalarının kendileri dışındaki girişlere bağlı olmasını kısıtlamak özellikle önemlidir.
Yani harici programları çalıştırmamalı, ağdan okuma yapmamalı veya uygun Task örnekleri olarak yürütme aşamasına ertelenebilecek uzun hesaplamalar yapmamalısınız.
Yürütme aşamasında
Yürütme aşamasında, istenen görevler ve bunlara bağlı görevler yürütülür. Özellikle, @TaskAction ile işaretlenmiş Task sınıfı yöntemleri yürütülür. Görev yürütme sırasında girişlerden (ör. dosyalar) okuma yapabilir ve Provider<T>.get() yöntemini çağırarak geç sağlayıcıları çözebilirsiniz. Yavaş sağlayıcıları bu şekilde çözmek, sağlayıcıda bulunan görev bağımlılığı bilgilerini izleyen bir dizi map() veya flatMap() çağrısı başlatır. Görevler, gerekli değerleri gerçekleştirmek için geç çalıştırılır.
Variant API, yapılar ve görevler
Variant API, Android Gradle eklentisinde bulunan bir uzantı mekanizmasıdır. Bu mekanizma, normalde derleme yapılandırma dosyalarında DSL kullanılarak ayarlanan ve Android derlemesini etkileyen çeşitli seçenekleri değiştirmenize olanak tanır. Variant API, derleme tarafından oluşturulan ara ve nihai yapılara (ör. sınıf dosyaları, birleştirilmiş manifest veya APK/AAB dosyaları) erişmenizi de sağlar.
Android derleme akışı ve uzantı noktaları
AGP ile etkileşim kurarken tipik Gradle yaşam döngüsü geri çağırma yöntemlerini (ör. afterEvaluate()) kaydetmek veya açık Task bağımlılıkları ayarlamak yerine özel olarak oluşturulmuş uzantı noktalarını kullanın. AGP tarafından oluşturulan görevler, uygulama ayrıntıları olarak kabul edilir ve herkese açık bir API olarak sunulmaz. Task nesnelerinin örneklerini almaya veya Task adlarını tahmin etmeye ve bu Task nesnelerine doğrudan geri çağırmalar ya da bağımlılıklar eklemeye çalışmaktan kaçınmanız gerekir.
AGP, Task örneklerini oluşturup yürütmek için aşağıdaki adımları tamamlar. Bu örnekler de derleme yapılarını oluşturur. Variant nesnesi oluşturma sürecindeki ana adımları, derleme kapsamında oluşturulan belirli nesnelerde değişiklik yapmanıza olanak tanıyan geri çağırmalar takip eder. Tüm geri çağırmaların yapılandırma aşamasında (bu sayfada açıklanmıştır) gerçekleştiğini ve hızlı bir şekilde çalışması gerektiğini unutmayın. Karmaşık işler, yürütme aşamasında uygun Task örneklerine ertelenmelidir.
- DSL ayrıştırma: Derleme komut dosyalarının değerlendirildiği ve
androidbloğundaki Android DSL nesnelerinin çeşitli özelliklerinin oluşturulup ayarlandığı aşamadır. Aşağıdaki bölümlerde açıklanan Variant API geri çağırmaları da bu aşamada kaydedilir. finalizeDsl(): DSL nesnelerini bileşen (varyant) oluşturma için kilitlenmeden önce değiştirmenize olanak tanıyan geri çağırma. DSL nesnelerinde bulunan verilere göreVariantBuildernesneleri oluşturulur.DSL kilitleme: DSL artık kilitlidir ve değişiklik yapılamaz.
beforeVariants(): Bu geri çağırma,VariantBuilderaracılığıyla hangi bileşenlerin oluşturulacağını ve bunların bazı özelliklerini etkileyebilir. Derleme akışında ve üretilen yapıtlarda değişiklik yapılmasına izin verir.Varyant oluşturma: Oluşturulacak bileşenlerin ve yapıların listesi artık kesinleşmiştir ve değiştirilemez.
onVariants(): Bu geri çağırmada, oluşturulanVariantnesnelerine erişebilir ve içerdikleriPropertydeğerleri için değerler veya sağlayıcılar ayarlayabilirsiniz. Bu değerler, gerektiğinde hesaplanır.Varyant kilitleme: Varyant nesneleri artık kilitlidir ve değişiklik yapılamaz.
Oluşturulan görevler: Derleme işlemini gerçekleştirmek için gereken
Taskörneklerini oluşturmak üzereVariantnesneleri ve bunlarınPropertydeğerleri kullanılır.
AGP, finalizeDsl(), beforeVariants() ve onVariants() için geri çağırma işlevleri kaydetmenize olanak tanıyan bir AndroidComponentsExtension sunar.
Uzantı, androidComponents bloğu aracılığıyla derleme komut dosyalarında kullanılabilir:
// This is used only for configuring the Android build through DSL.
android { ... }
// The androidComponents block is separate from the DSL.
androidComponents {
finalizeDsl { extension ->
...
}
}
Ancak derleme komut dosyalarını yalnızca android bloğunun DSL'sini kullanan açıklayıcı yapılandırma için kullanmanızı ve özel zorunlu mantıkları buildSrc dizinine veya harici eklentilere taşımanızı öneririz. Projenizde nasıl eklenti oluşturacağınızı öğrenmek için Gradle tarifleri GitHub depomuzdaki buildSrc örneklere de göz atabilirsiniz. Eklentinizin, derleme dosyanızdaki gradle-api yapısına göre derlendiğinden emin olun. Aşağıda, eklenti kodundan geri çağırmaları kaydetme örneği verilmiştir:
abstract class ExamplePlugin: Plugin<Project> {
override fun apply(project: Project) {
val androidComponents = project.extensions.getByType(AndroidComponentsExtension::class.java)
androidComponents.finalizeDsl { extension ->
...
}
}
}
Kullanılabilir geri çağırmaları ve eklentinizin her birinde destekleyebileceği kullanım alanlarını daha yakından inceleyelim:
finalizeDsl(callback: (DslExtensionT) -> Unit)
Bu geri çağırmada, derleme dosyalarındaki android bloğundan gelen bilgileri ayrıştırarak oluşturulan DSL nesnelerine erişebilir ve bunları değiştirebilirsiniz.
Bu DSL nesneleri, derlemenin sonraki aşamalarında varyantları başlatmak ve yapılandırmak için kullanılır. Örneğin, programatik olarak yeni yapılandırmalar oluşturabilir veya özellikleri geçersiz kılabilirsiniz. Ancak tüm değerlerin yapılandırma sırasında çözümlenmesi gerektiğini, bu nedenle harici girişlere bağlı olmaması gerektiğini unutmayın.
Bu geri çağırma işlevi yürütmeyi tamamladıktan sonra DSL nesneleri artık kullanışlı olmaz ve bunlara referans vermeniz veya değerlerini değiştirmeniz gerekmez.
abstract class ExamplePlugin: Plugin<Project> {
override fun apply(project: Project) {
val androidComponents = project.extensions.getByType(AndroidComponentsExtension::class.java)
androidComponents.finalizeDsl { extension ->
extension.buildTypes.create("extra").let {
it.isJniDebuggable = true
}
}
}
}
beforeVariants()
Derlemenin bu aşamasında, oluşturulacak varyantları ve özelliklerini belirleyen VariantBuilder nesnelerine erişebilirsiniz. Örneğin, belirli varyantları ve testlerini programatik olarak devre dışı bırakabilir veya bir özelliğin değerini (ör. minSdk) yalnızca seçilen bir varyant için değiştirebilirsiniz. finalizeDsl() parametresine benzer şekilde, sağladığınız tüm değerlerin yapılandırma sırasında çözümlenmesi gerekir ve harici girişlere bağlı olmamalıdır. beforeVariants() geri çağırma işlevinin yürütülmesi tamamlandıktan sonra VariantBuilder nesneleri değiştirilmemelidir.
androidComponents {
beforeVariants { variantBuilder ->
variantBuilder.minSdk = 23
}
}
beforeVariants() geri çağırma işlevi, isteğe bağlı olarak VariantSelector alır. Bunu androidComponentsExtension üzerindeki selector() yöntemiyle elde edebilirsiniz. Bu özelliği, geri çağırma çağrısına katılan bileşenleri adlarına, derleme türlerine veya ürün türlerine göre filtrelemek için kullanabilirsiniz.
androidComponents {
beforeVariants(selector().withName("adfree")) { variantBuilder ->
variantBuilder.minSdk = 23
}
}
onVariants()
onVariants() çağrıldığında, AGP tarafından oluşturulacak tüm yapılar zaten belirlenmiş olduğundan bunları artık devre dışı bırakamazsınız. Ancak görevler için kullanılan değerlerden bazılarını, Variant nesnelerindeki Property özellikleri için ayarlayarak değiştirebilirsiniz. Property değerleri yalnızca AGP'nin görevleri yürütüldüğünde çözümleneceğinden, bunları dosya veya ağ gibi harici girişlerden okuma dahil olmak üzere gerekli hesaplamaları yapacak kendi özel görevlerinizdeki sağlayıcılara güvenle bağlayabilirsiniz.
// onVariants also supports VariantSelectors:
onVariants(selector().withBuildType("release")) { variant ->
// Gather the output when we are in single mode (no multi-apk).
val mainOutput = variant.outputs.single { it.outputType == OutputType.SINGLE }
// Create version code generating task
val versionCodeTask = project.tasks.register("computeVersionCodeFor${variant.name}", VersionCodeTask::class.java) {
it.outputFile.set(project.layout.buildDirectory.file("${variant.name}/versionCode.txt"))
}
/**
* Wire version code from the task output.
* map() will create a lazy provider that:
* 1. Runs just before the consumer(s), ensuring that the producer
* (VersionCodeTask) has run and therefore the file is created.
* 2. Contains task dependency information so that the consumer(s) run after
* the producer.
*/
mainOutput.versionCode.set(versionCodeTask.map { it.outputFile.get().asFile.readText().toInt() })
}
Oluşturulan kaynakları derlemeye ekleme
Eklentiniz, aşağıdakiler gibi birkaç türde oluşturulan kaynak sağlayabilir:
javadizinindeki uygulama koduresdizinindeki Android kaynaklarıresourcesdizinindeki Java kaynaklarıassetsdizinindeki Android öğeleri
Ekleyebileceğiniz kaynakların tam listesi için Sources API'ye bakın.
Bu kod snippet'i, addStaticSourceDirectory() işlevini kullanarak Java kaynak grubuna ${variant.name} adlı özel bir kaynak klasörünün nasıl ekleneceğini gösterir. Android araç zinciri bu klasörü işler.
onVariants { variant ->
variant.sources.java?.let { java ->
java.addStaticSourceDirectory("custom/src/kotlin/${variant.name}")
}
}
Daha fazla bilgi için addJavaSource tarifine bakın.
Bu kod snippet'i, özel bir görevden oluşturulan Android kaynaklarını içeren bir dizinin res kaynak grubuna nasıl ekleneceğini gösterir. Süreç diğer kaynak türleri için de benzerdir.
onVariants(selector().withBuildType("release")) { variant ->
// Step 1. Register the task.
val resCreationTask =
project.tasks.register<ResCreatorTask>("create${variant.name}Res")
// Step 2. Register the task output to the variant-generated source directory.
variant.sources.res?.addGeneratedSourceDirectory(
resCreationTask,
ResCreatorTask::outputDirectory)
}
...
// Step 3. Define the task.
abstract class ResCreatorTask: DefaultTask() {
@get:OutputFiles
abstract val outputDirectory: DirectoryProperty
@TaskAction
fun taskAction() {
// Step 4. Generate your resources.
...
}
}
Daha fazla bilgi için addCustomAsset tarifine bakın.
Yapılara erişme ve yapıları değiştirme
AGP, Variant nesnelerindeki basit özellikleri değiştirmenize olanak tanımanın yanı sıra derleme sırasında üretilen ara ve nihai yapıları okumanızı veya dönüştürmenizi sağlayan bir uzantı mekanizması da içerir. Örneğin, birleştirilmiş son AndroidManifest.xml dosyasının içeriğini özel bir Task içinde okuyarak analiz edebilir veya içeriğini tamamen özel Task tarafından oluşturulan bir manifesto dosyasının içeriğiyle değiştirebilirsiniz.
Şu anda desteklenen yapıların listesini Artifact sınıfının referans belgelerinde bulabilirsiniz. Her yapı türünün bilinmesi faydalı olan belirli özellikleri vardır:
Nicelik
Bir Artifact öğesinin kardinalitesi, FileSystemLocation örneklerinin sayısını veya yapı türünün dosya ya da dizin sayısını temsil eder. Bir yapının kardinalitesi hakkında bilgi edinmek için üst sınıfını kontrol edebilirsiniz: Tek bir FileSystemLocation içeren yapılar Artifact.Single'nin alt sınıfı, birden fazla FileSystemLocation örneği içeren yapılar ise Artifact.Multiple'nin alt sınıfı olur.
FileSystemLocation türü
Bir Artifact öğesinin dosyaları mı yoksa dizinleri mi temsil ettiğini, parametreleştirilmiş FileSystemLocation türüne bakarak kontrol edebilirsiniz. Bu tür, RegularFile veya Directory olabilir.
Desteklenen işlemler
Her Artifact sınıfı, desteklediği işlemleri belirtmek için aşağıdaki arayüzlerden herhangi birini uygulayabilir:
Transformable: BirArtifactöğesinin, üzerinde rastgele dönüşümler gerçekleştiren veArtifactöğesinin yeni bir sürümünü oluşturan birTaskiçin giriş olarak kullanılmasına olanak tanır.Appendable: YalnızcaArtifact.Multiplealt sınıfları olan yapılar için geçerlidir. Bu,Artifactöğesine ekleme yapılabileceği, yani özel birTasköğesinin buArtifacttüründe yeni örnekler oluşturabileceği ve bu örneklerin mevcut listeye ekleneceği anlamına gelir.Replaceable: YalnızcaArtifact.Singlealt sınıfları olan yapılar için geçerlidir. Değiştirilebilir birArtifact,Taskçıkışı olarak üretilen tamamen yeni bir örnekle değiştirilebilir.
Yapıları değiştiren üç işleme ek olarak her yapı, yapının son sürümünü (üzerindeki tüm işlemler tamamlandıktan sonra) içeren bir Provider döndüren get() (veya getAll()) işlemini destekler.
Birden fazla eklenti, onVariants() geri çağırma işlevinden ardışık düzene herhangi bir sayıda yapı işlemi ekleyebilir. AGP, tüm görevlerin doğru zamanda çalıştırılması ve yapıların doğru şekilde üretilip güncellenmesi için bunların düzgün şekilde zincirlenmesini sağlar. Yani bir işlem, çıktıları ekleme, değiştirme veya dönüştürme yoluyla değiştirdiğinde bir sonraki işlem, bu yapıların güncellenmiş sürümünü giriş olarak görür.
İşlemleri kaydetme giriş noktası Artifacts sınıfıdır.
Aşağıdaki kod snippet'inde, onVariants() geri çağırma işlevindeki Variant nesnesinin bir özelliğinden Artifacts örneğine nasıl erişebileceğiniz gösterilmektedir.
Ardından, özel TaskProvider değerinizi ileterek bir TaskBasedOperation nesnesi (1) alabilir ve wiredWith* yöntemlerinden birini (2) kullanarak giriş ve çıkışlarını bağlamak için bu nesneyi kullanabilirsiniz.
Seçmeniz gereken yöntem, dönüştürmek istediğiniz Artifact tarafından uygulanan kardinaliteye ve FileSystemLocation türüne bağlıdır.
Son olarak, Artifact türünü, karşılığında aldığınız *OperationRequest nesnesinde seçilen işlemi temsil eden bir yönteme iletirsiniz. Örneğin, toAppendTo(), toTransform() veya toCreate() (3).
androidComponents.onVariants { variant ->
val manifestUpdater = // Custom task that will be used for the transform.
project.tasks.register(variant.name + "ManifestUpdater", ManifestTransformerTask::class.java) {
it.gitInfoFile.set(gitVersionProvider.flatMap(GitVersionTask::gitVersionOutputFile))
}
// (1) Register the TaskProvider w.
val variant.artifacts.use(manifestUpdater)
// (2) Connect the input and output files.
.wiredWithFiles(
ManifestTransformerTask::mergedManifest,
ManifestTransformerTask::updatedManifest)
// (3) Indicate the artifact and operation type.
.toTransform(SingleArtifact.MERGED_MANIFEST)
}
Bu örnekte MERGED_MANIFEST bir SingleArtifact ve RegularFile. Bu nedenle, giriş için tek bir RegularFileProperty referansı ve çıkış için tek bir RegularFileProperty kabul eden wiredWithFiles yöntemini kullanmamız gerekir. TaskBasedOperation sınıfında, diğer Artifact kardinalite ve FileSystemLocation türü kombinasyonları için kullanılabilecek başka wiredWith* yöntemleri de vardır.
AGP'yi genişletme hakkında daha fazla bilgi edinmek için Gradle derleme sistemi kılavuzundaki aşağıdaki bölümleri okumanızı öneririz:
- Özel Gradle Eklentileri Geliştirme
- Gradle eklentilerini uygulama
- Özel Gradle Görev Türleri Geliştirme
- Geç Yapılandırma
- Görev yapılandırmasından kaçınma