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 uygulamada birbirine 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şlevselliğini genişletmesi için uzantı noktaları içerir. AGP'nin önceki sürümlerinde, resmi API'ler dahili uygulamalardan net bir şekilde ayrılmamıştı. AGP, 7.0 sürümünden itibaren güvenebileceğiniz bir dizi resmi ve kararlı API'ye sahiptir.
AGP API yaşam döngüsü
AGP, API'lerinin durumunu belirtmek için Gradle özellik yaşam döngüsünü izler:
- Dahili: Herkese açık kullanım için tasarlanmamıştır.
- Geliştirme aşamasında: Herkese açık olarak kullanılabilir ancak son sürüm değildir. Bu nedenle, son 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 desteğinin sonlandırılması ve bunların yeni, kararlı API'ler ve yeni bir alana özgü dil (DSL) ile değiştirilmesiyle gelişiyor. Bu evrim, birden fazla AGP sürümünü kapsayacak. Bu konu hakkında daha fazla bilgiyi AGP API/DSL geçiş zaman çizelgesinde bulabilirsiniz.
AGP API'leri bu taşıma işlemi veya başka bir nedenle kullanımdan kaldırıldığında mevcut ana sürümde kullanılmaya devam edecek ancak uyarılar oluşturacaktır. Desteği sonlandırılan API'ler, sonraki ana sürümde AGP'den tamamen kaldırılacaktır. Örneğin, bir API AGP 7.0'da kullanımdan kaldırılırsa 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. Sık karşılaşılan derleme özelleştirmeleriyle ilgili örnekler sunar. Yeni API'ler hakkında daha fazla bilgiyi referans belgelerimizde bulabilirsiniz.
Gradle derleme temelleri
Bu kılavuzda Gradle derleme sisteminin tamamı ele alınmamaktadır. Ancak, API'lerimize entegre olmanıza yardımcı olacak minimum gerekli kavramlar kümesini kapsar ve daha fazla bilgi için ana Gradle dokümanlarına bağlantılar içerir.
Gradle'ın işleyişiyle ilgili temel bilgilere (ör. projeleri yapılandırma, derleme dosyalarını düzenleme, eklentileri uygulama ve görevleri çalıştırma) sahip olduğunuzu varsayıyoruz. AGP ile ilgili olarak Gradle'ın temelleri hakkında bilgi edinmek için Derlemenizi yapılandırma başlıklı makaleyi incelemenizi öneririz. Gradle eklentilerini özelleştirme ile ilgili genel çerçeve hakkında bilgi edinmek için Özel Gradle Eklentileri Geliştirme başlıklı makaleyi inceleyin.
Gradle tembel türleri sözlüğü
Gradle,"tembel" davranan veya ağır hesaplamaları ya da Task
oluşturmayı 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 temel Gradle türleri ve bunların temel yöntemleri yer almaktadır.
Provider<T>
T
türünde bir değer (burada "T" herhangi bir tür anlamına gelir) sağlar. Bu değer, yürütme aşamasındaget()
kullanılarak okunabilir veyamap()
,flatMap()
vezip()
yöntemleri kullanılarak yeni birProvider<S>
türüne (burada "S" başka bir tür anlamına gelir) dönüştürülebilir.get()
'nın yapılandırma aşamasında asla çağrılmaması gerektiğini unutmayın.map()
: Lambda kabul eder veS
türündeProvider
oluşturur,Provider<S>
.map()
işlevinin lambda bağımsız değişkeniT
değerini alır veS
değerini üretir. Lambda hemen yürütülmez. Bunun yerine, yürütülmesi, sonuçta elde edilenProvider<S>
üzerindeget()
çağrıldığında ertelenir ve tüm zincir tembel hale gelir.flatMap()
: Lambda işlevini de kabul eder veProvider<S>
değerini üretir ancak lambda işleviT
değerini alır veProvider<S>
değerini üretir (doğrudanS
değ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 konuşmak gerekirsemap()
kullandığınızdaProvider<Provider<S>>
sonuç türü elde ettiyseniz bunun nedeni muhtemelenflatMap()
kullanmanız gerektiğidir.zip()
: İkiProvider
örneğini birleştirerek yeni birProvider
oluşturmanıza olanak tanır. Bu yeniProvider
'ün değeri, iki girişProviders
örneğindeki değerleri birleştiren bir işlev kullanılarak hesaplanır.
Property<T>
- Uygulandığı için
Provider<T>
türünde bir değer de sağlar.T
Salt okunur olanProvider<T>
'nın aksineProperty<T>
için de bir değer ayarlayabilirsiniz. Bunu yapmanın iki yolu vardır:T
türünde bir değer, kullanılabilir olduğunda doğrudan ayarlanır. Bu işlem için ertelenmiş hesaplamalar gerekmez.Property<T>
değerinin kaynağı olarak başka birProvider<T>
ayarlayın. Bu durumda,T
değeri yalnızcaProperty.get()
çağrıldığında oluşturulur.
TaskProvider
- Uygulama
Provider<Task>
TaskProvider
oluşturmak içintasks.register()
kullanın. Görevlerin yalnızca gerektiğinde geç başlatıldığından emin olmak içintasks.create()
kullanmayın.Task
oluşturulmadan önceflatMap()
kullanarakTask
çıkışlarına erişebilirsiniz. Bu, çıkışları diğerTask
örneklerine giriş olarak kullanmak istediğinizde faydalı olabilir.
Sağlayıcılar ve bunların dönüştürme yöntemleri, görevlerin giriş ve çıkışlarını geç yükleme şeklinde ayarlamak için gereklidir. Bu sayede, tüm görevleri önceden oluşturup değerleri çözmeye gerek kalmaz.
Sağlayıcılar, görev bağımlılığı bilgilerini de taşır. Task
çıkışını dönüştürerek Provider
oluşturduğunuzda bu Task
, Provider
'nın örtülü bağımlılığı haline gelir ve Provider
'nın değeri çözümlendiğinde (ör. başka bir Task
tarafından gerektiğinde) oluşturulup çalıştırılır.
Aşağıda, GitVersionTask
ve ManifestProducerTask
olmak üzere iki görevin kaydedildiği, Task
örneklerinin oluşturulmasının ise gerçekten ihtiyaç duyulana kadar ertelendiği bir örnek verilmiştir. ManifestProducerTask
giriş değeri, GitVersionTask
çıkışından elde edilen bir Provider
olarak ayarlanır. Bu nedenle ManifestProducerTask
, GitVersionTask
'ye örtülü 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 istenirse yürütülür. Bu durum, örneğin ./gradlew
debugManifestProducer
komutunu çalıştırdığınızda veya ManifestProducerTask
komutunun çıkışı başka bir göreve bağlanıp değeri gerekli hale geldiğinde Gradle çağrısı kapsamında gerçekleşebilir.
Girişleri kullanan ve/veya çıkışlar üreten özel görevler yazsanı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, okuyup dönüştürebileceğiniz Variant API'yi ve görevlerinin çıkışına (veya build artifacts) erişimi sunar. Daha fazla bilgi için bu belgedeki Varyant API'si, 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. Tekrarlanabilir veya gereksiz hesaplamalara harcanan süreyi en aza indirmeye yardımcı olan görev yapılandırmasından kaçınma, güncel kontroller ve yapılandırma önbelleğe alma özelliği gibi çeşitli özellikler vardır.
Bu optimizasyonlardan bazılarını uygulamak için Gradle komut dosyaları ve eklentileri, her bir ayrı Gradle derleme aşamasında (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ü rehberinde 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, DSL nesnelerini kullanarak derlemeyi yapılandırmak ve görevleri ile girişlerini geç kaydetmek için kullanılmalıdır.
Yapılandırma aşaması, hangi görevin çalıştırılması istendiğinden bağımsız olarak her zaman çalıştığından bu aşamayı yalın tutmak ve hesaplamaların, derleme komut dosyalarının kendisi dışındaki girişlere bağlı olmasını kısıtlamak özellikle önemlidir.
Yani harici programlar yürütmemeli, 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ı
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 yapmanıza ve Provider<T>.get()
işlevini çağırarak geç yüklenen sağlayıcıları çözmenize izin verilir. Lazy 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ını başlatır. Görevler, gerekli değerleri oluşturmak için geç çalıştırılır.
Varyant API'si, yapılar ve görevler
Variant API, Android Gradle eklentisindeki bir uzantı mekanizmasıdır. Bu mekanizma, Android derlemesini etkileyen ve normalde derleme yapılandırma dosyalarında DSL kullanılarak ayarlanan çeşitli seçenekleri değiştirmenize olanak tanır. Variant API, derleme tarafından oluşturulan ara ve nihai yapıtlara (ör. sınıf dosyaları, birleştirilmiş manifest veya APK/AAB dosyaları) da erişmenizi sağlar.
Android derleme akışı ve uzantı noktaları
AGP ile etkileşimde bulunurken, normal Gradle yaşam döngüsü geri çağırmalarını (ö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 API olarak sunulmaz. Task
nesnelerinin örneklerini almaya çalışmaktan veya Task
adlarını tahmin etmekten ve bu Task
nesnelerine doğrudan geri çağırmalar ya da bağımlılıklar eklemekten 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ı üretir. Variant
Nesne oluşturmayla ilgili temel adımların ardından, derleme kapsamında oluşturulan belirli nesnelerde değişiklik yapmanıza olanak tanıyan geri çağırmalar gelir. 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ı çalışması gerektiğini, karmaşık işlemlerin ise yürütme aşamasında uygun Task
örneklerine ertelenmesi gerektiğini unutmayın.
- DSL ayrıştırma: Bu aşamada derleme komut dosyaları değerlendirilir ve
android
bloğundaki Android DSL nesnelerinin çeşitli özellikleri oluşturulup ayarlanır. Aşağıdaki bölümlerde açıklanan Variant API geri çağırmaları da bu aşamada kaydedilir. finalizeDsl()
: DSL nesnelerinin bileşen (varyant) oluşturma için kilitlenmeden önce değiştirilmesine olanak tanıyan geri çağırma.VariantBuilder
nesneleri, DSL nesnelerinde bulunan verilere göre oluşturulur.DSL kilitleme: DSL artık kilitli 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. Derleme akışında ve üretilen yapıtlar üzerinde değişiklik yapılmasına yine de izin verilir.Varyant oluşturma: Oluşturulacak bileşen ve yapıt listesi artık kesinleşti ve değiştirilemez.
onVariants()
: Bu geri çağırmada, oluşturulanVariant
nesnelerine erişebilir ve içerdikleriProperty
değerleri için değerler veya sağlayıcılar ayarlayabilirsiniz. Bu değerler geç hesaplanır.Varyant kilitleme: Varyant nesneleri artık kilitlendi ve değişiklik yapılamıyor.
Oluşturulan görevler:
Variant
nesneleri ve bunlarınProperty
değerleri, derleme işlemini gerçekleştirmek için gerekenTask
örneklerini oluşturmak üzere kullanılır.
AGP, finalizeDsl()
, beforeVariants()
ve onVariants()
için geri çağırmaları 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 kullanarak bildirim temelli yapılandırma için tutmanızı ve tüm özel zorunlu mantığı buildSrc
veya harici eklentilere taşımanızı öneririz. Projenizde eklenti oluşturmayı öğrenmek için Gradle tarifleri GitHub deposundaki buildSrc
örneklere de göz atabilirsiniz. Aşağıda, geri çağırma işlevlerini eklenti kodundan 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ılabilen geri çağırmalara ve eklentinizin her birinde destekleyebileceği kullanım alanlarına daha yakından bakalım:
finalizeDsl(callback: (DslExtensionT) -> Unit)
Bu geri çağırmada, derleme dosyalarındaki android
bloğundan alınan bilgilerin ayrıştırılmasıyla 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 ve bu nedenle herhangi bir harici girişe dayanmaması gerektiğini unutmayın.
Bu geri çağırma işlemi yürütmeyi tamamladıktan sonra DSL nesneleri artık kullanılamaz ve bunlara yönelik referansları tutmamalı ya da 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()
Oluşturma işleminin bu aşamasında, oluşturulacak varyantları ve bunların özelliklerini belirleyen VariantBuilder
nesnelerine erişebilirsiniz. Örneğin, belirli varyantları ve bunların 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()
'ya benzer şekilde, sağladığınız tüm değerler yapılandırma sırasında çözülmeli ve harici girişlere bağlı olmamalıdır. VariantBuilder
nesneleri, beforeVariants()
geri çağırma işlevi yürütülmeyi tamamladıktan sonra değiştirilmemelidir.
androidComponents {
beforeVariants { variantBuilder ->
variantBuilder.minSdk = 23
}
}
beforeVariants()
geri çağırması isteğe bağlı olarak VariantSelector
alır. Bu değeri androidComponentsExtension
üzerindeki selector()
yöntemiyle elde edebilirsiniz. Geri çağırma işlemine katılan bileşenleri adlarına, derleme türlerine veya ürün aromalarına 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 görevleri yürütüldüğünde çözümleneceğinden, bunları dosyalar veya ağ gibi harici girişlerden okuma da dahil olmak üzere gerekli tüm hesaplamaları yapacak kendi özel görevlerinizdeki 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 aşağıdaki gibi birkaç türde oluşturulmuş kaynak sağlayabilir:
java
dizinindeki uygulama kodures
dizinindeki Android kaynaklarıresources
dizinindeki Java kaynaklarıassets
dizinindeki Android öğeleri
Ekleyebileceğiniz kaynakların tam listesi için Kaynaklar API'si'ne bakın.
Bu kod snippet'i, addStaticSourceDirectory()
işlevini kullanarak Java kaynak kümesine ${variant.name}
adlı özel bir kaynak klasörünün nasıl ekleneceğini gösterir. Android araç zinciri daha sonra 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 kümesine nasıl ekleneceğini gösterir. Diğer kaynak türleri için de benzer bir süreç uygulanır.
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 bunları değiştirme
AGP, Variant
nesnelerindeki basit özellikleri değiştirmenize olanak tanımanın yanı sıra derleme sırasında oluşturulan ara ve nihai yapıtları okumanıza veya dönüştürmenize olanak tanıyan bir uzantı mekanizması da içerir. Örneğin, son birleştirilmiş AndroidManifest.xml
dosya içeriklerini özel bir Task
içinde okuyarak analiz edebilir veya içeriklerini tamamen özel Task
'niz tarafından oluşturulan bir manifest dosyasının içeriğiyle değiştirebilirsiniz.
Şu anda desteklenen yapıtların listesini Artifact
sınıfının referans belgelerinde bulabilirsiniz. Her yapay nesne türünün bilinmesi gereken belirli özellikleri vardır:
Kardinalite
Bir Artifact
öğesinin kardinalitesi, FileSystemLocation
örneklerinin sayısını veya yapıt türündeki dosya ya da dizinlerin sayısını gösterir. 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
sınıfının alt sınıfı olur. Birden fazla FileSystemLocation
örneği içeren yapılar ise Artifact.Multiple
sınıfının alt sınıfı olur.
FileSystemLocation
tür
Bir Artifact
öğesinin 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ı, hangi işlemleri desteklediğini 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 bir sürümünü çıkış olarak veren birTask
öğesine giriş olarak kullanılmasına olanak tanır.Appendable
: YalnızcaArtifact.Multiple
sınıfının alt sınıfları olan öğeler için geçerlidir. Bu,Artifact
öğesine ekleme yapılabileceği anlamına gelir. Yani özel birTask
, buArtifact
türünün yeni örneklerini oluşturabilir ve bu örnekler mevcut listeye eklenir.Replaceable
: YalnızcaArtifact.Single
sınıfının alt sınıfları olan öğeler için geçerlidir. Değiştirilebilir birArtifact
,Task
çıkışı olarak üretilen tamamen yeni bir örnekle değiştirilebilir.
Üç öğe değiştirme işlemine ek olarak her öğe, öğenin son sürümünü içeren bir get()
(veya getAll()
)
işlemini destekler. Bu işlem, öğe üzerindeki tüm işlemler tamamlandıktan sonra gerçekleştirilir.Provider
Birden fazla eklenti, onVariants()
geri çağırmasından itibaren işlem hattına herhangi bir sayıda işlem ekleyebilir. AGP, tüm görevlerin doğru zamanda çalışması ve yapıtların doğru şekilde üretilip güncellenmesi için bunların uygun şekilde zincirlenmesini sağlar. Yani bir işlem, çıktıları ekleyerek, değiştirerek veya dönüştürerek değiştirdiğinde sonraki işlem, bu öğelerin güncellenmiş sürümünü giriş olarak görür.
Kayıt işlemlerine giriş noktası Artifacts
sınıfıdır.
Aşağıdaki kod snippet'inde, onVariants()
geri çağırmasında Variant
nesnesindeki bir özellikten Artifacts
örneğine nasıl erişebileceğiniz gösterilmektedir.
Daha sonra, TaskBasedOperation
nesnesi (1) almak için özel TaskProvider
değerinizi iletebilir ve wiredWith*
yöntemlerinden (2) birini kullanarak giriş ve çıkışlarını bağlamak için 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, döndürülen *OperationRequest
nesnesinde seçilen işlemi temsil eden bir yönteme Artifact
türünü 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
öğesidir. Bu nedenle, giriş için tek bir RegularFileProperty
referansını, çıkış için ise tek bir RegularFileProperty
referansını kabul eden wiredWithFiles
yöntemini kullanmamız gerekir. wiredWith*
sınıfında, Artifact
kardinalite ve FileSystemLocation
türlerinin diğer kombinasyonları için çalışacak başka TaskBasedOperation
yöntemler 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ını Önleme