Android Gradle eklentisi (AGP), Android uygulamaları için resmi derleme sistemidir. Pek ç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 edilebilen yeni adımlar aracılığıyla işlevini genişletmesi için uzantı noktaları içerir. AGP'nin önceki sürümlerinde, resmi API'ler dahili uygulamalardan net bir şekilde ayrılmış değildi. 7.0 sürümünden itibaren AGP, güvenebileceğiniz bir dizi resmi ve kararlı API'ye sahiptir.
AGP API yaşam döngüsü
AGP, API'lerinin durumunu belirlemek için Gradle özelliği yaşam döngüsünü izler:
- Dahili: Herkese açık kullanım için tasarlanmamıştır
- Oluşturma: Herkese açık olarak kullanılabilir ancak nihai değil, yani nihai sürümde geriye dönük uyumlu olmayabilecekleri
- Herkese açık: Herkese açık ve kararlı olarak kullanılabilir.
- Kullanımdan kaldırıldı: Artık desteklenmiyor ve yeni API'lerle değiştirildi
Kullanımdan kaldırma politikası
Eski API'lerin kullanımdan kaldırılması ve bunların yeni, kararlı API'ler ve yeni bir Alana Özel Dil (DSL) ile değiştirilmesiyle AGP de gelişiyor. Bu gelişme, birden fazla AGP sürümünü kapsayacak. Bu konu hakkında daha fazla bilgiyi AGP API/DSL taşıma zaman çizelgesinde bulabilirsiniz.
AGP API'leri kullanımdan kaldırıldığında, bu taşıma işlemi için veya başka şekillerde, mevcut ana sürümde kullanılmaya devam edecek ancak uyarı oluşturacaktır. Desteği sonlandırılan API'ler, sonraki büyük 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ı oluşturur. Bu API artık AGP 8.0'da kullanılamayacak.
Yaygın derleme özelleştirmelerinde kullanılan yeni API örneklerini görmek için Android Gradle eklentisi tariflerine göz atın. Bu makalelerde, yaygın derleme özelleştirmelerine örnekler verilmiştir. Yeni API'ler hakkında daha fazla bilgiyi referans belgelerimizde de bulabilirsiniz.
Gradle derlemeyle ilgili temel bilgiler
Bu kılavuzda Gradle derleme sisteminin tamamı ele alınmamaktadır. Ancak bu kılavuzda, API'lerimizle entegrasyon yapmanıza yardımcı olacak minimum kavramlar ele alınmaktadır ve daha fazla bilgi edinmeniz için ana Gradle dokümanlarına yönlendiren bağlantılar bulunur.
Projeleri yapılandırma, derleme dosyalarını düzenleme, eklentileri uygulama ve görevleri çalıştırma dahil olmak üzere Gradle'in işleyiş şekli hakkında temel düzeyde bilgi sahibi olduğunuzu varsayıyoruz. AGP ile ilgili Gradle'ın temelleri hakkında bilgi edinmek için Derlemenizi yapılandırma bölümünü 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'da yavaş türler sözlüğü
Gradle, "geç" davranan veya ağır hesaplamaları ya da Task
oluşturma işlemini derlemenin sonraki aşamalarına ertelemeye yardımcı olan çeşitli türler sunar. Bu türler, birçok Gradle ve AGP API'sinin temelinde yer alır. Aşağıdaki listede geç yürütmede kullanılan ana Gradle türleri ve bunların temel yöntemleri yer almaktadır.
Provider<T>
get()
kullanılarak yürütme aşamasında okunabilen veyamap()
,flatMap()
vezip()
yöntemleri kullanılarak yeni birProvider<S>
'e dönüştürülebilenT
türündeki bir değer sağlar ("T" herhangi bir türü ifade eder).get()
işlevinin yapılandırma aşamasında hiçbir zaman çağrılmaması gerektiğini unutmayın.map()
: Lambda kabul eder veS
türünde birProvider
oluşturur,Provider<S>
.map()
işlevinin lambda bağımsız değişkeni,T
değerini alır veS
değerini döndürür. Lambda hemen yürütülmez. Bunun yerine, yürütülmesi, elde edilenProvider<S>
üzerindeget()
çağrılana kadar ertelenir. Bu da zincirin tamamını tembel hale getirir.flatMap()
: Lambda'yı da kabul eder veProvider<S>
değerini döndürür ancak lambda,T
değerini alır veProvider<S>
değerini döndürür (doğrudanS
değerini döndürmek yerine). Yapılandırma zamanında S belirlenemediğinde ve yalnızcaProvider<S>
elde edebildiğinizdeFlatMap() işlevini kullanın. Pratiktemap()
kullandıysanız ve birProvider<Provider<S>>
sonuç türü elde ettiyseniz muhtemelenflatMap()
sonuç türünü kullanmanız gerekirdi.zip()
: İkiProvider
örneğini birleştirerek yeni birProvider
oluşturmanıza olanak tanır. BuProvider
, iki girişProviders
örneğindeki değerleri birleştiren bir işlev kullanılarak hesaplanır.
Property<T>
- ,
Provider<T>
'ü uygular. Bu nedenle,T
türüne ait bir değer de sağlar. Salt okunur olanProvider<T>
'in aksineProperty<T>
için de değer ayarlayabilirsiniz. Bunu yapmanın iki yolu vardır:- Kullanılabilir olduğunda, ertelenmiş hesaplamalara gerek kalmadan doğrudan
T
türünde bir değer ayarlayın. Property<T>
değerinin kaynağı olarak başka birProvider<T>
ayarlayın. Bu durumdaT
değeri yalnızcaProperty.get()
çağrıldığında somutlaştırılır.
- Kullanılabilir olduğunda, ertelenmiş hesaplamalara gerek kalmadan doğrudan
TaskProvider
Provider<Task>
uygular.TaskProvider
oluşturmak içintasks.create()
yerinetasks.register()
kullanın. Böylece, görevlerin yalnızca gerektiğinde yavaşça oluşturulmasını sağlayabilirsiniz.Task
oluşturulmadan önceTask
'ın çıkışlarına erişmek içinflatMap()
'ü kullanabilirsiniz. Bu, çıkışları diğerTask
örneklerine giriş olarak kullanmak istiyorsanız yararlı olabilir.
Sağlayıcılar ve dönüşüm yöntemleri, görevlerin giriş ve çıkışlarını tembel bir şekilde ayarlamak için gereklidir. Yani tüm görevleri önceden oluşturmak ve değerleri çözmek gerekmez.
Sağlayıcılar görev bağımlılık bilgilerini de taşır. Bir Task
çıkışını dönüştürerek Provider
oluşturduğunuzda, bu Task
Provider
'nin gizli bir bağımlılığı haline gelir ve Provider
'nin değeri çözüldüğünde (ör. başka bir Task
bunu gerektirdiğinde) oluşturulur ve çalıştırılır.
GitVersionTask
ve ManifestProducerTask
adlı iki görevi kaydederken Task
örneklerinin oluşturulmasını gerçekten gerekli olana kadar ertelemeyle ilgili bir örneği burada bulabilirsiniz. ManifestProducerTask
giriş değeri, GitVersionTask
çıktısından elde edilen bir Provider
olarak ayarlanır. Bu nedenle ManifestProducerTask
, GitVersionTask
'ye dolaylı olarak 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 istenmeleri durumunda yürütülür. Bu durum, Gradle çağrısı kapsamında gerçekleşebilir. Örneğin, ./gradlew
debugManifestProducer
çalıştırırsanız veya ManifestProducerTask
işlevinin çıkışı başka bir göreve bağlanırsa ve değeri gerekli hale gelirse bu durum gerçekleşebilir.
Girişleri tüketen ve/veya çıkışlar üreten özel görevler yazsanız da AGP, kendi görevlerine doğrudan kamusal erişim sunmaz. Sürümden sürüme değişebilen bir uygulama ayrıntısıdır. Bunun yerine AGP, Variant API'yi ve görevlerin çıktısına veya okuyup dönüştürebileceğiniz derleme yapılarına erişim sunar. Daha fazla bilgi için bu dokümanda Variant API, Yapılar ve Görevler bölümüne bakın.
Gradle derleme aşamaları
Proje oluşturma işlemi, doğası gereği karmaşık ve kaynak gerektiren bir süreçtir. Yinelenebilir veya gereksiz hesaplamalara harcanan zamanı en aza indirmeye yardımcı olan görev yapılandırmasından kaçınma, güncel kontroller ve yapılandırma önbelleğe alma gibi çeşitli özellikler vardır.
Bu optimizasyonlardan bazılarını uygulamak için Gradle komut dosyalarının ve eklentilerinin, farklı Gradle derleme aşamalarının her biri (başlatma, yapılandırma ve yürütme) sırasında katı kurallara uyması gerekir. 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ülür. Bu aşama, derlemeyi DSL nesnelerini kullanarak 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ının istendiğine bakılmaksızın her zaman çalıştığından, bu aşamanın basit tutulması ve tüm hesaplamaların derleme komut dosyalarının kendisinden başka girişlere bağlı olmasının kısıtlanması özellikle önemlidir.
Yani harici programları çalıştırmamalı, ağdan veri okumamalı veya uygun Task
örnekleri olarak yürütme aşamasına ertelenebilir 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şaretlenen Task
sınıf yöntemleri yürütülür. Görev yürütülürken girişlerden (ör. dosyalar) okumanıza ve Provider<T>.get()
'ü çağırarak tembel sağlayıcıları çözmenize izin verilir. Tembel sağlayıcıları bu şekilde çözmek, sağlayıcıda bulunan görev bağımlılık bilgilerini izleyen bir dizi map()
veya flatMap()
çağrısı başlatır. Gerekli değerleri somutlaştırmak için görevler yavaşça çalıştırılır.
Varyant API'si, Yapılar ve Görevler
Variant API, Android Gradle eklentisinde yer alan bir uzantı mekanizmasıdır. Bu seçenek normalde, derleme yapılandırma dosyalarında DSL kullanılarak Android derlemesini etkileyen çeşitli seçenekleri manipüle etmenize olanak tanır. Variant API, derleme tarafından oluşturulan sınıf dosyaları, birleştirilmiş manifest veya APK/AAB dosyaları gibi ara ve nihai yapı öğelerine de erişim sağlar.
Android derleme akış ve uzantı noktaları
AGP ile etkileşim kurarken tipik Gradle yaşam döngüsü geri çağırmalarını (ör. afterEvaluate()
) kaydetmek veya açık Task
bağımlılıkları oluşturmak yerine özel olarak oluşturulmuş uzantı noktaları kullanın. AGP tarafından oluşturulan görevler, uygulama ayrıntıları olarak kabul edilir ve herkese açık bir API olarak kullanıma sunulmaz. Task
nesnelerinin örneklerini almaya çalışmaktan veya Task
adlarını tahmin etmekten ve doğrudan bu Task
nesnelerine geri çağırma ya da bağımlılık eklemekten kaçınmanız gerekir.
AGP, Task
örneklerini oluşturmak ve yürütmek için aşağıdaki adımları tamamlar ve böylece derleme yapıları oluşturulur. Variant
öğesi oluşturma ile ilgili ana adımlardan sonra, derleme kapsamında oluşturulan belirli öğelerde değişiklik yapmanıza olanak tanıyan geri çağırma işlevleri gelir. Tüm geri çağırma çağrılarının yapılandırma aşamasında (bu sayfada açıklanmıştır) gerçekleştiğini ve hızlı bir şekilde çalıştığını, karmaşık tüm işlemlerin yürütme aşamasında uygun Task
örneklerine ertelendiğine dikkat etmek önemlidir.
- DSL ayrıştırma: Bu, derleme komut dosyalarının değerlendirildiği ve
android
bloğundaki Android DSL nesnelerinin çeşitli özelliklerinin oluşturulup ayarlandığı anlamına gelir. Aşağıdaki bölümlerde açıklanan Variant API geri çağırma işlevleri de 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 işlevi.VariantBuilder
nesneleri, DSL nesnelerinde bulunan verilere göre oluşturulur.DSL kilitleme: DSL artık kilitlidir ve değişiklik yapılamaz.
beforeVariants()
: Bu geri çağırma,VariantBuilder
aracılığıyla hangi bileşenlerin oluşturulacağını ve bazı özelliklerini etkileyebilir. Bu durumda bile derleme akışında ve üretilen yapı taşlarında değişiklik yapmaya devam edebilirsiniz.Varyant oluşturma: Oluşturulacak bileşen ve yapıların listesi artık tamamlanmıştır ve değiştirilemez.
onVariants()
: Bu geri çağırmada, oluşturulanVariant
nesnelerine erişirsiniz ve içerdikleriProperty
değerleri için geç hesaplanacak değerleri veya sağlayıcıları ayarlayabilirsiniz.Varyant kilitleme: Varyant nesneleri artık kilitlenmiştir ve değişiklikler yapılamaz.
Oluşturulan görevler: Derlemeyi gerçekleştirmek için gerekli olan
Task
örneklerini oluşturmak amacıylaVariant
nesneleri ve bunlarınProperty
değerleri kullanılır.
AGP, finalizeDsl()
, beforeVariants()
ve onVariants()
için geri çağırma işlevleri kaydetmenize olanak tanıyan bir AndroidComponentsExtension
sunar.
Uzantı, derleme komut dosyalarında androidComponents
bloğu aracılığıyla 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 kullanarak açıklayıcı yapılandırma için kullanmanızı ve özel zorunlu mantığı buildSrc
veya harici eklentilere taşımanızı öneririz. Projenizde nasıl eklenti oluşturacağınızı öğrenmek için Gradle tarifleri GitHub depomuzda bulunan buildSrc
örneklerine de göz atabilirsiniz. Burada, eklenti kodundan geri çağırmaların kaydedilmesine ilişkin bir örnek 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ğırmalara ve eklentinizin her birinde destekleyebileceği kullanım alanı türlerine daha yakından bakalım:
finalizeDsl(callback: (DslExtensionT) -> Unit)
Bu geri çağırmada, derleme dosyalarında android
bloğundaki 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ı kalmamaları gerektiğini unutmayın.
Bu geri çağırma işlevi tamamlandıktan sonra DSL nesneleri artık yararlı değildir ve bu nesnelere referans vermemeli veya değerlerini değiştirmemelisiniz.
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 bunların özelliklerini belirleyen VariantBuilder
nesneye erişebilirsiniz. Örneğin, programatik olarak belirli varyantları ve testlerini devre dışı bırakabilir veya özelliğin değerini (örneğin, minSdk
) yalnızca seçilen bir varyant için değiştirebilirsiniz. finalizeDsl()
özelliğine benzer şekilde, sağladığınız tüm değerler yapılandırma zamanında çözümlenmelidir ve harici girişlere bağlı değildir. beforeVariants()
geri çağırma işlevinin yürütülmesi sona erdiğinde VariantBuilder
nesneleri değiştirilmemelidir.
androidComponents {
beforeVariants { variantBuilder ->
variantBuilder.minSdk = 23
}
}
beforeVariants()
geri çağırma işlevi isteğe bağlı olarak bir VariantSelector
alır. androidComponentsExtension
üzerindeki selector()
yöntemini kullanarak bu değeri elde edebilirsiniz. Geri çağırma çağrısına katılan bileşenleri adlarına, derleme türüne veya ürün çeşidine 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 halihazırda belirlenmiş olduğu için bunları artık devre dışı bırakamazsınız. Bununla birlikte, 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üleceğinden, bunları dosya veya ağ gibi harici girişlerden okuma da dahil olmak üzere gerekli tüm hesaplamaları yapacak olan kendi özel görevlerinizden sağlayıcılara güvenli bir şekilde 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, oluşturulan birkaç türde kaynağa katkıda bulunabilir. Örneğin:
java
dizinindeki uygulama kodures
dizininde Android kaynaklarıresources
dizinindeki Java kaynaklarıassets
dizininde Android öğeleri
Ekleyebileceğiniz kaynakların tam listesi için Sources API'ye bakın.
Bu kod snippet'i, addStaticSourceDirectory()
işlevi kullanılarak Java kaynak kümesine ${variant.name}
adlı özel kaynak klasörünün nasıl ekleneceğini göstermektedir. Ardından Android araç seti 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'inde, özel bir görevden oluşturulan Android kaynaklarını içeren bir dizinin res
kaynak grubuna nasıl ekleneceği gösterilmektedir. 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şim ve yapıları değiştirme
AGP, Variant
nesneleri üzerindeki basit özellikleri değiştirmenize izin vermenin yanı sıra derleme sırasında üretilen ara ve nihai yapıları okumanıza veya dönüştürmenize olanak tanıyan bir uzantı mekanizması da içerir. Örneğin, birleştirilmiş nihai AndroidManifest.xml
dosya içeriğini özel bir Task
'da okuyarak analiz edebilir veya içeriğini tamamen özel Task
'unuz tarafından oluşturulan bir manifest dosyasının içeriğiyle değiştirebilirsiniz.
Şu anda desteklenen yapıların listesini Artifact
sınıfının referans dokümanlarında bulabilirsiniz. Her yapı türü, bilinmesi yararlı olan belirli özelliklere sahiptir:
Kardinalite
Bir Artifact
öğesinin kardinalitesi, FileSystemLocation
örnek sayısını veya yapı türündeki 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ın alt sınıfı Artifact.Single
, birden fazla FileSystemLocation
örneği içeren yapıların alt sınıfı ise Artifact.Multiple
olur.
FileSystemLocation
tür
Bir Artifact
değerinin dosyaları mı yoksa dizinleri mi temsil ettiğini, parametrelendirilmiş 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
:Artifact
öğesinin, üzerinde rastgele dönüşümler gerçekleştiren veArtifact
öğesinin yeni sürümünü üretenTask
için giriş olarak kullanılmasına olanak tanır.Appendable
: YalnızcaArtifact.Multiple
öğesinin alt sınıfları olan yapılar için geçerlidir. Bu,Artifact
öğesinin eklenebilir olduğu anlamına gelir. Yani özel birTask
, mevcut listeye eklenecek buArtifact
türüne ait yeni örnekler oluşturabilir.Replaceable
: YalnızcaArtifact.Single
öğesinin alt sınıfları olan yapılar için geçerlidir. Değiştirilebilir birArtifact
,Task
çıktısı olarak üretilen tamamen yeni bir örnekle değiştirilebilir.
Her yapı, yapıyı değiştiren üç işleme ek olarak bir get()
(veya getAll()
) işlemini destekler. Bu işlem, yapının nihai sürümünü (yapıdaki tüm işlemler tamamlandıktan sonra) içeren bir Provider
döndürür.
Birden çok eklenti, onVariants()
geri çağırma işlevinden yapılar üzerindeki herhangi bir sayıda işlemi ardışık düzene ekleyebilir. AGP, tüm görevlerin doğru zamanda çalışması ve yapıların doğru şekilde oluşturulup güncellenmesi için bunların düzgün şekilde zincirlenmesini sağlar. Bu, bir işlem herhangi bir çıktıyı ekleyerek, değiştirerek veya dönüştürerek değiştirdiğinde bir sonraki işlemin bu yapıların güncellenmiş sürümünü giriş olarak göreceği anlamına gelir.
Kayıt işlemlerinin giriş noktası Artifacts
sınıfıdır.
Aşağıdaki kod snippet'i, onVariants()
geri çağırma işlevinde Variant
nesnesindeki bir mülkten Artifacts
örneğine nasıl erişim sağlayabileceğinizi gösterir.
Daha sonra özel TaskProvider
ileterek bir TaskBasedOperation
nesnesi (1) elde edebilir ve bunu, wiredWith*
yöntemlerinden (2) birini kullanarak giriş ve çıkışlarını bağlamak için kullanabilirsiniz.
Seçmeniz gereken tam 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ü, döndürülen *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
hem SingleArtifact
hem de RegularFile
öğesidir. Bu nedenle, giriş için tek bir RegularFileProperty
ve çıkış için de tek bir RegularFileProperty
referansı kabul eden wiredWithFiles
yöntemini kullanmamız gerekiyor. TaskBasedOperation
sınıfında, diğer Artifact
kardinalite ve FileSystemLocation
türü kombinasyonları için çalışacak başka wiredWith*
yöntemleri 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