Plugin Android Gradle (AGP) adalah sistem build resmi untuk aplikasi Android. Plugin ini mencakup dukungan untuk mengompilasi berbagai jenis sumber dan menautkannya ke dalam aplikasi yang dapat Anda jalankan pada perangkat Android fisik atau emulator.
AGP berisi titik ekstensi untuk plugin agar dapat mengontrol input build dan memperluas fungsinya melalui langkah-langkah baru yang dapat diintegrasikan dengan tugas build standar. Versi AGP versi sebelumnya tidak memiliki API resmi yang terpisah dengan jelas dari implementasi internal. Mulai dari versi 7.0, AGP memiliki kumpulan API resmi dan stabil yang dapat Anda andalkan.
Siklus proses AGP API
AGP mengikuti siklus proses fitur Gradle untuk menetapkan status API-nya:
- Internal: Tidak dimaksudkan untuk penggunaan umum
- Inkubasi: Tersedia untuk penggunaan publik, tetapi tidak bersifat final, yang berarti mungkin tidak kompatibel dengan versi akhir
- Publik: Tersedia untuk penggunaan publik dan stabil
- Tidak digunakan lagi: Tidak lagi didukung, dan digantikan dengan API baru
Kebijakan penghentian layanan
AGP berkembang dengan penghentian API lama dan penggantiannya dengan API baru yang stabil dan Domain Specific Language (DSL) baru. Evolusi ini akan mencakup beberapa rilis AGP, dan Anda dapat mempelajarinya lebih lanjut di linimasa migrasi AGP API/DSL.
Jika AGP API tidak digunakan lagi, untuk migrasi ini, jika tidak, API tersebut akan terus tersedia dalam rilis utama saat ini, tetapi akan menghasilkan peringatan. API yang tidak digunakan lagi akan sepenuhnya dihapus dari AGP dalam rilis utama berikutnya. Misalnya, jika API tidak digunakan lagi di AGP 7.0, API tersebut akan tersedia dalam versi tersebut dan menghasilkan peringatan. API tersebut tidak akan lagi tersedia di AGP 8.0.
Untuk melihat contoh API baru yang digunakan dalam penyesuaian build umum, lihat resep plugin Android Gradle. Resep ini memberikan contoh penyesuaian build umum. Anda juga dapat menemukan detail lebih lanjut tentang API baru di dokumentasi referensi kami.
Dasar-dasar build Gradle
Panduan ini tidak mencakup seluruh sistem build Gradle. Namun, panduan ini mencakup kumpulan konsep minimum yang diperlukan untuk membantu Anda berintegrasi dengan API kami, dan menautkan ke dokumentasi Gradle utama untuk dibaca lebih lanjut.
Kami mengasumsikan pengetahuan dasar tentang cara kerja Gradle, termasuk cara mengonfigurasi project, mengedit file build, menerapkan plugin, dan menjalankan tugas. Untuk mempelajari dasar-dasar Gradle sehubungan dengan AGP, sebaiknya tinjau Mengonfigurasi build Anda. Untuk mempelajari framework umum untuk menyesuaikan plugin Gradle, lihat Mengembangkan Plugin Gradle Kustom.
Glosarium jenis lambat Gradle
Gradle menawarkan sejumlah jenis perilaku "secara lambat", atau membantu menunda
komputasi berat
atau pembuatan
Task
ke fase build berikutnya. Jenis ini adalah inti dari banyak
Gradle API dan AGP API. Daftar berikut mencakup jenis Gradle utama yang terlibat
dalam eksekusi lambat, serta metode utamanya.
Provider<T>
- Memberikan nilai jenis
T
(dengan "T" berarti jenis apa pun), yang dapat dibaca selama fase eksekusi menggunakanget()
atau diubah menjadiProvider<S>
baru (dengan "S" berarti jenis lain) menggunakan metodemap()
,flatMap()
, danzip()
. Perhatikan bahwaget()
tidak boleh dipanggil selama fase konfigurasi.map()
: Menerima lambda dan menghasilkanProvider
jenisS
,Provider<S>
. Argumen lambda untukmap()
mengambil nilaiT
dan menghasilkan nilaiS
. Lambda tidak dieksekusi secara langsung; sebagai gantinya, eksekusinya ditunda pada saatget()
dipanggil padaProvider<S>
yang dihasilkan, membuat seluruh rantai menjadi lambat.flatMap()
: Juga menerima lambda dan menghasilkanProvider<S>
, tetapi lambda mengambilT
nilai dan menghasilkanProvider<S>
(bukan menghasilkanS
nilai secara langsung). Gunakan flatMap() saat S tidak dapat ditentukan pada waktu konfigurasi dan Anda hanya dapat memperolehProvider<S>
. Dari sudut pandang praktis, jika Anda menggunakanmap()
dan mendapatkan jenis hasilProvider<Provider<S>>
, itu berarti Anda harus menggunakanflatMap()
sebagai gantinya.zip()
: Memungkinkan Anda menggabungkan dua instanceProvider
untuk menghasilkanProvider
baru, dengan nilai yang dikomputasi menggunakan fungsi yang menggabungkan nilai dari dua instanceProviders
input.
Property<T>
- Mengimplementasikan
Provider<T>
, sehingga juga memberikan nilai jenisT
. Berbeda denganProvider<T>
yang bersifat hanya baca, Anda juga dapat menetapkan nilai untukProperty<T>
. Ada dua cara untuk melakukannya:- Tetapkan nilai jenis
T
secara langsung saat tersedia, tanpa perlu komputasi yang ditangguhkan. - Tetapkan
Provider<T>
lainnya sebagai sumber nilaiProperty<T>
. Dalam hal ini, nilaiT
hanya terwujud saatProperty.get()
dipanggil.
- Tetapkan nilai jenis
TaskProvider
- Mengimplementasikan
Provider<Task>
. Untuk menghasilkanTaskProvider
, gunakantasks.register()
, bukantasks.create()
, untuk memastikan tugas hanya dibuat instance-nya dengan lambat saat diperlukan. Anda dapat menggunakanflatMap()
untuk mengakses outputTask
sebelumTask
dibuat, yang dapat berguna jika Anda ingin menggunakan output tersebut sebagai input ke instanceTask
lainnya.
Penyedia dan metode transformasinya sangat penting untuk menyiapkan input dan output tugas secara lambat, yaitu, tanpa perlu membuat semua tugas terlebih dahulu dan menyelesaikan nilainya.
Penyedia juga membawa informasi dependensi tugas. Saat Anda membuat Provider
dengan
mengubah output Task
, Task
tersebut akan menjadi dependensi implisit
Provider
dan akan dibuat serta dijalankan setiap kali nilai Provider
diselesaikan, seperti ketika Task
lain memerlukannya.
Berikut adalah contoh untuk mendaftarkan dua tugas, GitVersionTask
dan
ManifestProducerTask
, saat menunda pembuatan instance Task
hingga
benar-benar diperlukan. Nilai input ManifestProducerTask
disetel ke
Provider
yang diperoleh dari output GitVersionTask
, sehingga
ManifestProducerTask
secara implisit bergantung pada GitVersionTask
.
// 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))
}
Kedua tugas ini hanya akan dijalankan jika diminta secara eksplisit. Hal ini dapat
terjadi sebagai bagian dari pemanggilan Gradle, misalnya, jika Anda menjalankan ./gradlew
debugManifestProducer
, atau jika output ManifestProducerTask
terhubung
ke beberapa tugas lain dan nilainya menjadi diperlukan.
Meskipun Anda akan menulis tugas kustom yang menggunakan input dan/atau menghasilkan output, AGP tidak menawarkan akses publik ke tugasnya sendiri secara langsung. Itu adalah detail implementasi yang dapat berubah dari versi ke versi. Sebagai gantinya, AGP menawarkan Variant API dan akses ke output tugasnya, atau artefak build, yang dapat Anda baca dan ubah. Lihat Variant API, Artefak, dan Tugas dalam dokumen ini untuk informasi selengkapnya.
Fase build Gradle
Membuat project secara inheren merupakan proses yang rumit dan membutuhkan resource, dan ada berbagai fitur seperti penghindaran konfigurasi tugas, pemeriksaan terbaru, dan fitur caching konfigurasi yang membantu meminimalkan waktu yang dihabiskan pada komputasi yang dapat direproduksi atau tidak diperlukan.
Untuk menerapkan beberapa pengoptimalan ini, skrip dan plugin Gradle harus mematuhi aturan yang ketat selama setiap fase build Gradle yang berbeda: inisialisasi, konfigurasi, dan eksekusi. Dalam panduan ini, kita akan berfokus pada fase konfigurasi dan eksekusi. Anda dapat menemukan informasi selengkapnya tentang semua fase dalam panduan siklus proses build Gradle.
Fase konfigurasi
Selama fase konfigurasi, skrip build untuk semua project yang merupakan bagian dari build dievaluasi, plugin akan diterapkan, dan dependensi build akan diselesaikan. Fase ini harus digunakan untuk mengonfigurasi build menggunakan objek DSL dan untuk mendaftarkan tugas dan inputnya dengan lambat.
Karena fase konfigurasi selalu berjalan, terlepas dari tugas yang
diminta untuk berjalan, penting untuk menjaganya tetap ramping dan membatasi
komputasi apa pun agar tidak bergantung pada input selain skrip build itu sendiri.
Artinya, sebaiknya Anda tidak menjalankan program eksternal atau membaca dari jaringan, atau
melakukan komputasi panjang yang dapat ditunda ke fase eksekusi sebagai instance
Task
yang tepat.
Fase eksekusi
Pada fase eksekusi, tugas yang diminta dan tugas dependennya
akan dieksekusi. Secara khusus, metode class Task
yang ditandai dengan @TaskAction
akan dieksekusi. Selama eksekusi tugas, Anda diizinkan untuk membaca dari input (seperti
file) dan menyelesaikan penyedia lambat dengan memanggil Provider<T>.get()
. Menyelesaikan penyedia lambat
dengan cara ini akan memulai urutan panggilan map()
atau flatMap()
yang mengikuti
informasi dependensi tugas yang ada dalam penyedia. Tugas berjalan
dengan lambat untuk mewujudkan nilai yang diperlukan.
Variant API, Artefak, dan Tugas
Variant API adalah mekanisme ekstensi di plugin Android Gradle yang memungkinkan Anda memanipulasi berbagai opsi, yang biasanya ditetapkan menggunakan DSL dalam file konfigurasi build, yang memengaruhi build Android. Variant API juga memberi Anda akses ke artefak perantara dan final yang dibuat oleh build, seperti file class, manifes gabungan, atau file APK/AAB.
Alur build dan titik ekstensi Android
Saat berinteraksi dengan AGP, gunakan titik ekstensi yang dibuat khusus, bukan
mendaftarkan callback siklus proses Gradle standar (seperti afterEvaluate()
) atau
menyiapkan dependensi Task
eksplisit. Tugas yang dibuat oleh AGP dianggap
detail implementasi dan tidak ditampilkan sebagai API publik. Anda sebaiknya
jangan mencoba mendapatkan instance objek Task
atau menebak nama Task
dan menambahkan callback atau dependensi ke objek Task
tersebut secara langsung.
AGP menyelesaikan langkah-langkah berikut untuk membuat dan menjalankan instance Task
,
yang pada akhirnya menghasilkan artefak build. Langkah utama yang terlibat dalam pembuatan objek
Variant
diikuti dengan callback yang memungkinkan Anda membuat perubahan pada
objek tertentu yang dibuat sebagai bagian dari build. Penting untuk diperhatikan bahwa semua
callback terjadi selama fase konfigurasi
(dijelaskan di halaman ini) dan harus berjalan cepat. Oleh karena itu, sebagai gantinya, pekerjaan
yang rumit untuk instance Task
yang tepat selama fase eksekusi akan ditunda.
- Penguraian DSL: Ini adalah saat skrip build dievaluasi, dan saat
berbagai properti objek Android DSL dari blok
android
dibuat dan disetel. Callback Variant API yang dijelaskan di bagian berikut juga terdaftar selama fase ini. finalizeDsl()
: Callback yang memungkinkan Anda mengubah objek DSL sebelum dikunci untuk pembuatan komponen (varian). ObjekVariantBuilder
dibuat berdasarkan data yang dimuat dalam objek DSL.Penguncian DSL: DSL kini dikunci dan tidak lagi dapat diubah.
beforeVariants()
: Callback ini dapat memengaruhi komponen yang dibuat, dan beberapa propertinya, melaluiVariantBuilder
. Callback masih memungkinkan modifikasi pada alur build dan artefak yang dihasilkan.Pembuatan varian: Daftar komponen dan artefak yang akan dibuat kini telah diselesaikan dan tidak dapat diubah.
onVariants()
: Dalam callback ini, Anda mendapatkan akses ke objekVariant
yang dibuat dan Anda dapat menetapkan nilai atau penyedia untuk nilaiProperty
yang dimuatnya agar dikomputasi dengan lambat.Penguncian varian: Objek varian kini dikunci dan tidak lagi dapat diubah.
Tugas yang dibuat: Objek
Variant
beserta nilaiProperty
-nya digunakan untuk membuat instanceTask
yang diperlukan untuk menjalankan build.
AGP memperkenalkan
AndroidComponentsExtension
, yang memungkinkan
Anda mendaftarkan callback untuk finalizeDsl()
, beforeVariants()
, dan onVariants()
.
Ekstensi ini tersedia dalam skrip build melalui blok androidComponents
:
// This is used only for configuring the Android build through DSL.
android { ... }
// The androidComponents block is separate from the DSL.
androidComponents {
finalizeDsl { extension ->
...
}
}
Namun, sebaiknya simpan skrip build hanya untuk konfigurasi
deklaratif menggunakan DSL blok Android dan
pindahkan logika imperatif kustom ke buildSrc
atau plugin eksternal. Anda juga dapat melihat contoh buildSrc
di repositori GitHub urutan langkah Gradle untuk mempelajari cara membuat plugin dalam project Anda. Berikut adalah contoh pendaftaran callback dari kode plugin:
abstract class ExamplePlugin: Plugin<Project> {
override fun apply(project: Project) {
val androidComponents = project.extensions.getByType(AndroidComponentsExtension::class.java)
androidComponents.finalizeDsl { extension ->
...
}
}
}
Mari ketahui lebih lanjut callback yang tersedia dan jenis kasus penggunaan yang dapat didukung oleh plugin Anda di setiap callback:
finalizeDsl(callback: (DslExtensionT) -> Unit)
Dalam callback ini, Anda dapat mengakses dan mengubah objek DSL yang
dibuat dengan menguraikan informasi dari blok android
dalam file build.
Objek DSL ini akan digunakan untuk melakukan inisialisasi dan mengonfigurasi varian dalam
fase build selanjutnya. Misalnya, Anda dapat membuat konfigurasi
baru atau mengganti properti secara terprogram—tetapi perlu diingat bahwa semua nilai harus
diselesaikan pada waktu konfigurasi, sehingga nilai tersebut tidak boleh bergantung pada input eksternal.
Setelah callback ini selesai dijalankan, objek DSL tidak lagi berguna dan
Anda tidak boleh lagi menyimpan referensi ke objek tersebut atau memodifikasi nilainya.
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()
Pada tahap build ini, Anda mendapatkan akses ke objek VariantBuilder
, yang
menentukan varian yang akan dibuat dan propertinya. Misalnya,
Anda dapat secara terprogram menonaktifkan varian tertentu, pengujiannya, atau mengubah
nilai properti (misalnya, minSdk
) hanya untuk varian yang dipilih. Mirip dengan
finalizeDsl()
, semua nilai yang Anda berikan harus diselesaikan pada waktu
konfigurasi dan tidak bergantung pada input eksternal. Objek VariantBuilder
tidak boleh
diubah setelah eksekusi callback beforeVariants()
selesai.
androidComponents {
beforeVariants { variantBuilder ->
variantBuilder.minSdk = 23
}
}
Callback beforeVariants()
secara opsional mengambil VariantSelector
, yang dapat Anda
peroleh melalui metode selector()
padaandroidComponentsExtension
. Anda dapat
menggunakannya untuk memfilter komponen yang berpartisipasi dalam pemanggilan callback berdasarkan
nama, jenis build, atau ragam produknya.
androidComponents {
beforeVariants(selector().withName("adfree")) { variantBuilder ->
variantBuilder.minSdk = 23
}
}
onVariants()
Saat onVariants()
dipanggil, semua artefak yang akan dibuat oleh
AGP sudah ditentukan, sehingga Anda tidak dapat menonaktifkannya lagi. Namun, Anda dapat
mengubah beberapa nilai yang digunakan untuk tugas dengan menetapkannya untuk
atribut Property
dalam objek Variant
. Karena nilai Property
hanya akan
diselesaikan ketika tugas AGP dijalankan, Anda dapat menghubungkannya dengan aman ke
penyedia dari tugas kustom Anda sendiri yang akan melakukan
komputasi apa pun yang diperlukan, termasuk membaca dari input eksternal seperti file atau jaringan.
// 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() })
}
Memberikan kontribusi pada sumber yang dihasilkan ke build
Plugin Anda dapat berkontribusi pada beberapa jenis sumber yang dihasilkan, seperti:
- Kode aplikasi di direktori
java
- Resource Android di
direktori
res
- Resource Java
di direktori
resources
- Aset Android di
direktori
assets
Untuk mengetahui daftar lengkap sumber yang dapat Anda tambahkan, lihat Sources API.
Cuplikan kode ini menunjukkan cara menambahkan folder sumber kustom yang bernama
${variant.name}
ke set sumber Java menggunakan fungsi
addStaticSourceDirectory()
. Selanjutnya, toolchain Android akan memproses folder ini.
onVariants { variant ->
variant.sources.java?.let { java ->
java.addStaticSourceDirectory("custom/src/kotlin/${variant.name}")
}
}
Lihat urutan langkah addJavaSource untuk mengetahui detail selengkapnya.
Cuplikan kode ini menunjukkan cara menambahkan direktori dengan resource Android
yang dihasilkan dari tugas kustom ke set sumber res
. Proses ini mirip dengan
jenis sumber lainnya.
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.
...
}
}
Lihat urutan langkah addCustomAsset untuk mengetahui detail selengkapnya.
Mengakses dan mengubah artefak
Selain memungkinkan Anda mengubah properti sederhana pada objek Variant
, AGP
juga berisi mekanisme ekstensi yang memungkinkan Anda membaca atau mengubah
artefak perantara dan final yang dihasilkan selama proses build. Misalnya, Anda dapat
membaca konten file AndroidManifest.xml
final yang digabungkan dalam Task
kustom untuk
menganalisisnya, atau Anda dapat sepenuhnya mengganti kontennya dengan file manifes
yang dihasilkan oleh Task
kustom Anda.
Anda dapat menemukan daftar artefak yang saat ini didukung dalam dokumentasi
referensi untuk class Artifact
. Setiap jenis artefak memiliki properti tertentu yang akan sangat bermanfaat:
Kardinalitas
Kardinalitas Artifact
mewakili jumlah instance FileSystemLocation
,
atau jumlah file atau direktori jenis artefak. Anda dapat
memperoleh informasi tentang kardinalitas artefak dengan memeriksa class
induknya: Artefak dengan satu FileSystemLocation
akan menjadi subclass
Artifact.Single
; artefak dengan beberapa instance FileSystemLocation
akan
menjadi subclass Artifact.Multiple
.
Jenis FileSystemLocation
Anda dapat memeriksa apakah Artifact
mewakili file atau direktori dengan melihat
jenis FileSystemLocation
yang diparameterisasinya, yang dapat berupa RegularFile
atau
Directory
.
Operasi yang didukung
Setiap class Artifact
dapat mengimplementasikan salah satu antarmuka berikut untuk menunjukkan
operasi mana yang didukungnya:
Transformable
: MemungkinkanArtifact
untuk digunakan sebagai input keTask
yang melakukan transformasi arbitrer di dalamnya dan meng-output versi baruArtifact
.Appendable
: Hanya berlaku untuk artefak yang merupakan subclassArtifact.Multiple
. Ini berartiArtifact
dapat ditambahkan, yaitu,Task
kustom dapat membuat instance baru dari jenisArtifact
ini yang akan ditambahkan ke daftar yang ada.Replaceable
: Hanya berlaku untuk artefak yang merupakan subclassArtifact.Single
.Artifact
yang dapat diganti dapat diganti dengan instance yang benar-benar baru, yang dihasilkan sebagai outputTask
.
Selain tiga operasi modifikasi artefak, setiap artefak mendukung operasi
get()
(atau getAll()
),
yang menampilkan Provider
dengan versi final artefak
(setelah semua operasi di dalamnya selesai).
Beberapa plugin dapat menambahkan sejumlah operasi pada artefak ke dalam pipeline
dari callback onVariants()
, dan AGP akan memastikan semuanya dirantai dengan benar sehingga
semua tugas berjalan pada waktu yang tepat dan artefak dihasilkan dengan benar dan
diperbarui. Ini berarti saat operasi mengubah output dengan menambahkan,
mengganti, atau mengubahnya, operasi berikutnya akan melihat artefak dalam
versi terbaru sebagai input, dan sebagainya.
Titik entri ke operasi pendaftaran adalah class Artifacts
.
Cuplikan kode berikut menunjukkan cara Anda dapat mengakses instance
Artifacts
dari properti di objek Variant
dalam callback
onVariants()
.
Kemudian, Anda dapat meneruskan TaskProvider
kustom untuk mendapatkan objek
TaskBasedOperation
(1), dan menggunakannya untuk menghubungkan input dan outputnya menggunakan salah satu
metode wiredWith*
(2).
Metode tepat yang harus Anda pilih bergantung pada kardinalitas dan
jenis FileSystemLocation
yang diimplementasikan oleh Artifact
yang ingin Anda ubah.
Terakhir, Anda meneruskan jenis Artifact
ke metode yang mewakili
operasi yang dipilih pada objek *OperationRequest
yang Anda dapatkan sebagai gantinya, misalnya,
toAppendTo()
,
toTransform()
, atau 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)
}
Dalam contoh ini, MERGED_MANIFEST
adalah SingleArtifact
, dan merupakan
RegularFile
. Karena itu, kita perlu menggunakan metode wiredWithFiles
, yang
menerima satu referensi RegularFileProperty
untuk input, dan
satu RegularFileProperty
untuk output. Ada metode wiredWith*
lain di
class TaskBasedOperation
yang akan berfungsi untuk kombinasi lain dari jenis kardinalitas
Artifact
dan FileSystemLocation
.
Untuk mempelajari lebih lanjut cara memperluas AGP, sebaiknya baca bagian berikut dari panduan sistem build Gradle:
- Mengembangkan Plugin Gradle Kustom
- Mengimplementasikan plugin Gradle
- Mengembangkan Jenis Tugas Gradle Kustom
- Konfigurasi Lambat
- Menghindari Konfigurasi Tugas