Bagaimana Cara Menggabungkan beberapa file manifes pada ANDROID STUDIO?
File APK Anda hanya bisa berisi satu file
AndroidManifest.xml, tetapi project Android Studio dapat berisi beberapa file, yang disediakan oleh kumpulan sumber utama, varian build, dan library yang diimpor. Jadi, saat membuat aplikasi, build Gradle akan menggabungkan semua file manifes ke dalam satu file manifes tunggal yang dipaketkan ke dalam APK Anda.
Alat bantu penggabung manifes mengombinasikan semua elemen XML dari setiap file dengan mengikuti beberapa heuristik penggabungan dan dengan mematuhi preferensi penggabungan yang telah didefinisikan dengan atribut XML khusus. Halaman ini menjelaskan cara kerja penggabungan manifes dan cara menerapkan preferensi penggabungan untuk mengatasi konflik penggabungan.
Tips: Gunakan Tampilan Manifes Gabungan untuk melihat pratinjau hasil manifes yang digabungkan dan menemukan error konflik.
Prioritas penggabungan
Alat bantu penggabung akan mengombinasikan semua file manifes ke dalam satu file dengan menggabungkannya secara berurutan berdasarkan prioritas setiap file manifes. Misalnya, jika Anda memiliki tiga file manifes, manifes berprioritas terendah akan digabungkan ke prioritas tertinggi berikutnya, lalu digabungkan lagi ke dalam manifes berprioritas tertinggi seperti yang diilustrasikan dalam gambar 1.

Gambar 1. Proses menggabungkan tiga file manifes, prioritas terendah (kiri) ke dalam prioritas tertinggi (kanan)
Ada tiga tipe dasar file manifes yang bisa digabungkan satu sama lain, dan prioritas penggabungannya adalah sebagai berikut (prioritas tertinggi terlebih dahulu):
- File manifes untuk varian build AndaJika Anda memiliki beberapa kumpulan sumber untuk varian, prioritas manifesnya adalah sebagai berikut:
- Manifes varian build (seperti
src/demoDebug/) - Manifes tipe build (seperti
src/debug/) - Manifes ragam produk (seperti
src/demo/)Jika Anda menggunakan dimensi ragam, prioritas manifesnya akan menyesuaikan urutan pencantuman setiap dimensi dalam propertiflavorDimensions(pertama adalah prioritas tertinggi).
- Manifes varian build (seperti
- File manifes utama untuk modul aplikasi
- File manifes dari library yang disertakanJika Anda memiliki beberapa library, prioritas manifesnya akan dicocokkan dengan urutan dependensinya (urutan kemunculannya dalam blok
dependenciesGradle Anda).
Misalnya, sebuah manifes library digabungkan ke dalam manifes utama, lalu manifes utama tersebut digabungkan ke dalam manifes varian build.
Penting: Konfigurasi build dari file
build.gradle menggantikan setiap atribut yang terkait dalam file manifes gabungan. Misalnya, minSdkVersion dari file build.gradle menggantikan atribut yang cocok dalam elemen manifes <uses-sdk>. Agar tidak bingung, cukup biarkan elemen <uses-sdk> dan tentukan properti ini hanya dalam file build.gradle. Untuk mengetahui detail selengkapnya, lihat Mengonfigurasi build Anda.Heuristik konflik penggabungan
Alat bantu penggabung secara logis bisa mencocokkan setiap elemen XML dari satu manifes ke elemen yang bersesuaian di manifes lainnya. (Untuk mengetahui detail tentang cara kerja pencocokan, lihat apendiks tentang kebijakan penggabungan).
Jika elemen dari manifes yang berprioritas lebih rendah tidak cocok dengan elemen apa pun dalam manifes yang berprioritas lebih tinggi, manifes akan ditambahkan ke manifes gabungan. Namun, jika ada elemen yang cocok, alat bantu penggabung akan mencoba mengombinasikan semua atribut ke dalam satu elemen yang sama. Jika alat bantu menemukan bahwa kedua manifes berisi atribut yang sama dengan nilai berbeda, konflik penggabungan akan terjadi.
Tabel 1 menggambarkan kemungkinan hasil ketika alat bantu penggabung mencoba menyatukan semua atribut ke dalam elemen yang sama.
Tabel 1. Perilaku penggabungan default untuk nilai atribut
| Atribut prioritas tinggi | Atribut prioritas rendah | Hasil penggabungan atribut |
|---|---|---|
| Tidak ada nilai | Tidak ada nilai | Tidak ada nilai (menggunakan nilai default) |
| Nilai B | Nilai B | |
| Nilai A | Tidak ada nilai | Nilai A |
| Nilai A | Nilai A | |
| Nilai B | Error konflik, tambahkan pembuat aturan penggabungan |
Namun, ada beberapa situasi ketika alat bantu penggabung berperilaku berbeda untuk menghindari konflik penggabungan:
- Atribut dalam elemen
<manifest>tidak pernah digabungkan bersama, hanya atribut dari manifes prioritas tertinggi yang digunakan. - Atribut
android:requireddalam elemen<uses-feature>dan<uses-library>menggunakan penggabungan OR sehingga jika ada konflik,"true"akan diterapkan dan fitur atau library yang diperlukan oleh satu manifes akan selalu disertakan. - Atribut dalam elemen
<uses-sdk>selalu menggunakan nilai dari manifes yang berprioritas lebih tinggi, kecuali dalam situasi berikut:- Saat manifes yang berprioritas lebih rendah memiliki nilai
minSdkVersionyang lebih tinggi, error akan terjadi kecuali Anda menerapkan aturan penggabunganoverrideLibrary. - Saat manifes yang berprioritas lebih rendah memiliki nilai
targetSdkVersionyang lebih rendah, alat bantu penggabung akan menggunakan nilai dari manifes yang berprioritas lebih tinggi, tetapi juga menambahkan setiap izin yang diperlukan untuk memastikan bahwa library yang diimpor tetap berfungsi dengan benar (seandainya versi Android yang lebih tinggi telah meningkatkan pembatasan izin). Untuk informasi selengkapnya tentang perilaku ini, lihat bagian tentang izin sistem implisit.
- Saat manifes yang berprioritas lebih rendah memiliki nilai
- Elemen
<intent-filter>tidak pernah dicocokkan di antara manifes yang ada. Masing-masing diperlakukan secara unik dan ditambahkan ke elemen induk biasa di manifes gabungan.
Untuk semua konflik antar atribut lainnya, Anda akan menerima pesan error dan harus memberi tahu alat bantu penggabung tentang cara mengatasinya dengan menambahkan atribut khusus dalam file manifes yang berprioritas lebih tinggi (lihat bagian berikutnya tentang penanda aturan penggabungan).
Jangan bergantung pada nilai-nilai atribut default. Karena semua atribut unik dikombinasikan ke dalam elemen yang sama, maka hal ini dapat menyebabkan hasil yang tidak diharapkan jika manifes yang berprioritas lebih tinggi sebenarnya bergantung pada nilai default suatu atribut tanpa mendeklarasikannya. Contohnya, jika manifes yang berprioritas lebih tinggi tidak mendeklarasikan atribut
android:launchMode, maka nilai default "standard"akan digunakan; tetapi jika manifes yang berprioritas lebih rendah mendeklarasikan atribut ini dengan nilai yang berbeda, nilai tersebut akan diterapkan ke manifes gabungan (yang akan menggantikan nilai default). Jadi, sebaiknya tentukan setiap atribut secara eksplisit sesuai yang Anda inginkan. (Nilai default untuk setiap atribut didokumentasikan dalam Referensi manifes.)Penanda aturan penggabungan
Penanda aturan penggabungan adalah atribut XML yang bisa Anda gunakan untuk menyatakan preferensi Anda tentang cara mengatasi konflik penggabungan atau membuang elemen dan atribut yang tidak diinginkan. Anda bisa menerapkan penanda ke seluruh elemen atau hanya pada atribut tertentu dalam elemen.
Saat menggabungkan dua file manifes, alat bantu penggabung akan mencari penanda ini dalam file manifes yang berprioritas lebih tinggi.
Semua penanda dimiliki oleh namespace
tools Android, jadi Anda harus mendeklarasikan namespace ini dalam elemen <manifest> seperti yang ditampilkan berikut ini:Penanda node
Untuk menerapkan aturan penggabungan pada keseluruhan elemen XML (ke semua atribut dalam manifes elemen yang diberikan dan ke semua turunannya), gunakan atribut berikut:
tools:node="merge"- Menggabungkan semua atribut dalam tag ini dan semua elemen terserang jika tidak ada konflik dengan menggunakan heuristik konflik penggabungan. Ini adalah perilaku default elemen.Manifes berprioritas rendah:Manifes berprioritas tinggi:Hasil manifes gabungan:
tools:node="merge-only-attributes"- Menggabungkan atribut dalam tag ini saja; tidak menggabungkan elemen tersarang.Manifes berprioritas rendah:Manifes berprioritas tinggi:Hasil manifes gabungan:
tools:node="remove"- Menghapus elemen ini dari manifes gabungan. Meskipun sepertinya Anda cukup menghapus elemen ini, penggunaannya diperlukan jika Anda menemukan elemen di manifes gabungan yang tidak dibutuhkan, dan elemen itu disediakan oleh file manifes yang berprioritas lebih rendah yang berada di luar kendali Anda (seperti library yang diimpor).Manifes berprioritas rendah:Manifes berprioritas tinggi:Hasil manifes gabungan:
tools:node="removeAll"- Seperti
tools:node="remove", tetapi membuang semua elemen yang cocok dengan jenis elemen ini (dalam elemen induk yang sama).Manifes berprioritas rendah:Manifes berprioritas tinggi:Hasil manifes gabungan: tools:node="replace"- Mengganti seluruh elemen yang berprioritas lebih rendah. Artinya, jika ada elemen yang cocok dalam manifes yang berprioritas lebih rendah, abaikan elemen ini persis sebagaimana munculnya dalam manifes.Manifes berprioritas rendah:Manifes berprioritas tinggi:Hasil manifes gabungan:
tools:node="strict"- Menghasilkan kegagalan build jika elemen di manifes yang berprioritas lebih rendah tidak sama persis dengan elemen di manifes yang berprioritas lebih tinggi (kecuali jika telah ditangani oleh penanda aturan penggabungan lainnya). Ini menggantikan heuristik konflik penggabungan. Misalnya, jika manifes yang berprioritas lebih rendah hanya menyertakan atribut ekstra, build akan gagal (karena perilaku default menambahkan atribut ekstra ke manifes gabungan).Manifes berprioritas rendah:Manifes berprioritas tinggi:Kode ini akan mengakibatkan error penggabungan manifes. Kedua elemen manifes tidak bisa dibedakan sama sekali di mode ketat. Jadi, Anda harus menerapkan penanda aturan penggabungan lain untuk mengatasi perbedaan ini. (Biasanya, keduanya akan bergabung bersama dengan baik seperti yang ditampilkan dalam contoh di atas untuk
tools:node="merge".)
Penanda atribut
Untuk menerapkan aturan penggabungan hanya pada atribut tertentu di tag manifes, gunakan atribut berikut ini. Setiap atribut menerima satu atau beberapa nama atribut (termasuk namespace atribut), yang dipisah dengan koma.
tools:remove="attr, ..."- Membuang atribut yang ditentukan dari manifes gabungan. Meskipun sepertinya Anda cukup menghapus atribut ini, Anda perlu menggunakannya ketika file manifes yang berprioritas lebih rendah menyertakanatribut ini dan Anda ingin memastikan atribut ini tidak disertakan ke manifes gabungan.Manifes berprioritas rendah:Manifes berprioritas tinggi:Hasil manifes gabungan:
tools:replace="attr, ..."- Mengganti atribut yang ditetapkan dalam manifes yang berprioritas lebih rendah dengan atribut dari manifes ini. Dengan kata lain, selalu mempertahankan nilai manifes yang berprioritas lebih tinggi.Manifes berprioritas rendah:Manifes berprioritas tinggi:Hasil manifes gabungan:
tools:strict="attr, ..."- Menghasilkan kegagalan build jika atribut dalam manifes yang berprioritas lebih rendah ini tidak sama persis dengan atribut dalam manifes yang berprioritas lebih tinggi. Ini adalah perilaku default untuk semua atribut, kecuali yang memiliki perilaku khusus seperti yang dijelaskan dalam heuristik konflik penggabungan.Manifes berprioritas rendah:Manifes berprioritas tinggi:Kode ini akan menghasilkan error penggabungan manifes. Anda harus menerapkan penanda aturan penggabungan lain untuk mengatasi konflik. (Ingat: Ini adalah perilaku default, jadi contoh di atas memiliki hasil yang sama jika Anda membuang
tools:strict="screenOrientation".)
Anda juga bisa menerapkan beberapa penanda ke satu elemen seperti berikut.
Manifes berprioritas rendah:
Manifes berprioritas tinggi:
Hasil manifes gabungan:
Pemilih penanda
Jika Anda ingin menerapkan penanda aturan penggabungan ke library tertentu yang diimpor, tambahkan atribut
tools:selector dengan nama paket library.
Misalnya, dengan manifes berikut ini, aturan penggabungan
remove hanya diterapkan jika file manifes yang berprioritas lebih rendah berasal dari library com.example.lib1.
Jika manifes yang berprioritas lebih rendah berasal dari sumber lainnya, aturan penggabungan
remove akan diabaikan.
Catatan: Jika Anda menggunakan aturan ini dengan salah satu penanda atribut, maka akan diterapkan ke semua atribut yang ditetapkan dalam penanda.
Mengganti <uses-sdk> untuk library yang diimpor
Secara default, saat mengimpor library dengan nilai
minSdkVersion yang lebih tinggi daripada file manifes utama project, akan terjadi error dan library tidak bisa diimpor. Agar alat bantu penggabung mengabaikan konflik ini dan mengimpor library dengan mempertahankan nilai minSdkVersion yang lebih rendah di aplikasi Anda, tambahkan atribut overrideLibrary ke tag <uses-sdk>. Nilai atribut bisa berupa salah satu atau beberapa nama paket library (yang dipisahkan koma), menunjukkan library yang bisa menggantikanminSdkVersion manifes utama.
Misalnya, jika manifes utama Anda aplikasi menerapkan
overrideLibrary seperti ini:
Maka manifes berikut ini bisa digabungkan tanpa error berkenaan dengan tag
<uses-sdk>, dan manifes gabungan mempertahankan minSdkVersion="2" dari manifes aplikasi.Izin sistem implisit
Beberapa API Android yang semula bebas diakses oleh aplikasi kini dibatasi oleh izin sistem di versi terbaru Android. Agar tidak merusak aplikasi yang mengharapkan akses ke API ini, versi terbaru Android kembali mengizinkan aplikasi untuk mengakses API tersebut tanpa izin jika telah menyetel
targetSdkVersion ke nilai yang lebih rendah daripada versi yang telah ditambahkan pembatasan. Perilaku ini secara efektif memberikan izin implisit ke aplikasi yang mengizinkannya mengakses API tersebut. Jadi, hal ini bisa memengaruhi manifes gabungan yang memiliki nilai-nilai berbeda untuk targetSdkVersion dengan cara berikut ini.
Jika file manifes yang berprioritas lebih rendah memiliki nilai lebih rendah untuk
targetSdkVersion yang memberinya izin implisit, dan manifes yang berprioritas lebih tinggi tidak memiliki izin implisit yang sama (karena targetSdkVersion-nya sama dengan atau lebih tinggi daripada versi yang telah ditambahkan pembatasan), maka alat bantu penggabung secara eksplisit akan menambahkan izin sistem ke manifes gabungan.
Misalnya, jika aplikasi Anda menyetel
targetSdkVersion ke 4 atau lebih tinggi lalu mengimpor library dengan targetSdkVersion yang disetel ke 3 atau lebih rendah, alat bantu penggabung akan menambahkan izin WRITE_EXTERNAL_STORAGE ke manifes gabungan. Tabel 2 mencantumkan semua kemungkinan izin yang bisa ditambahkan ke manifes gabungan.
Tabel 2. Daftar izin yang bisa ditambahkan oleh alat bantu penggabung ke manifes gabungan
| Manifes berprioritas lebih rendah mendeklarasikan | Izin yang ditambahkan ke manifes gabungan |
|---|---|
targetSdkVersion adalah 3 atau lebih rendah | WRITE_EXTERNAL_STORAGE, READ_PHONE_STATE |
targetSdkVersion adalah 15 atau lebih rendah dan menggunakan READ_CONTACTS | READ_CALL_LOG |
targetSdkVersion adalah 15 atau lebih rendah dan menggunakan WRITE_CONTACTS | WRITE_CALL_LOG |
Memeriksa manifes gabungan dan menemukan konflik
Bahkan sebelum membuat APK, Anda bisa melihat pratinjau tampilan manifes gabungan tersebut dengan membuka file
AndroidManifest.xml di Android Studio, lalu mengklik tab Manifes Gabungan (Merged Manifest) di bagian bawah editor.
Tampilan Manifes Gabungan menampilkan hasil manifes gabungan di sebelah kiri, dan informasi tentang setiap file manifes gabungan di sebelah kanan, seperti yang ditampilkan dalam gambar 2. Elemen yang digabungkan dari file manifes berprioritas lebih rendah disorot dalam warna yang berbeda di sebelah kiri. Kunci untuk setiap warna ditentukan dalam Sumber Manifes (Manifest Sources) di sebelah kanan.

Gambar 2. Tampilan Manifes Gabungan
File manifes yang merupakan bagian build tetapi tidak menyumbangkan elemen atau atribut dicantumkan dalam File Manifes Lainnya (Other Manifest Files) di sebelah kanan.
Untuk melihat informasi tentang asal elemen, klik elemen tersebut di sebelah kiri dan detailnya akan muncul dalam Log Penggabungan (Merging Log) di sebelah kanan.
Jika terjadi konflik, detailnya akan muncul dalam Error Penggabungan (Merging Errors) di sebelah kanan dengan rekomendasi tentang cara mengatasinya menggunakan penanda aturan penggabungan. Error ini juga dicantumkan di jendela Event Log (pilih View > Tool Windows > Event Log).
Jika ingin melihat log lengkap tentang pohon keputusan penggabungan, temukan file log dalam direktori
build/outputs/logs/ modul Anda, bernama manifest-merger-buildVariant-report.txt.Apendiks: Kebijakan penggabungan
Alat bantu penggabung manifes secara logis bisa mencocokkan setiap elemen XML dari satu file manifes ke elemen yang bersesuaian di file lainnya. Penggabung akan mencocokkan setiap elemen dengan menggunakan "kunci pencocokan": berupa nilai atribut unik (misalnya
android:name) atau sifat unik alami dari tag itu sendiri (misalnya, hanya boleh ada satu elemen <supports-screen>). Jika dua manifes memiliki elemen XML yang sama, maka alat bantu akan menggabungkan kedua elemen dengan menggunakan salah satu dari tiga kebijakan penggabungan:- Gabungkan
- Mengombinasikan semua atribut yang tidak berkonflik ke dalam tag yang sama dan menggabungkan elemen turunan sesuai kebijakan penggabungannya masing-masing. Jika ada atribut yang saling bertentangan, gabungkan dengan penanda aturan penggabungan.
- Gabungkan turunan saja
- Tidak mengombinasikan atau menggabungkan atribut (hanya mempertahankan atribut yang disediakan oleh file manifes yang berprioritas tertinggi) dan menggabungkan elemen turunan sesuai kebijakan penggabungannya.
- Pertahankan
- Membiarkan elemen "apa adanya" dan menambahkannya ke elemen induk biasa dalam file gabungan. Kebijakan ini hanya digunakan jika sejumlah deklarasi elemen yang sama diperbolehkan.
Tabel 1 mencantumkan setiap tipe elemen, tipe kebijakan penggabungan yang digunakan, dan kunci yang digunakan untuk menentukan elemen yang cocok di antara kedua manifes.
Tabel 3. Kebijakan penggabungan elemen manifes dan kunci pencocokan
| Elemen | Kebijakan penggabungan | Kunci pencocokan |
|---|---|---|
<action> | Gabungkan | Atribut android:name |
<activity> | Gabungkan | Atribut android:name |
<application> | Gabungkan | Hanya ada satu per <manifest> |
<category> | Gabungkan | Atribut android:name |
<data> | Gabungkan | Hanya ada satu per <intent-filter> |
<grant-uri-permission> | Gabungkan | Hanya ada satu per <provider> |
<instrumentation> | Gabungkan | Atribut android:name |
<intent-filter> | Pertahankan | Tidak ada pencocokan; beberapa deklarasi dalam elemen induk diizinkan |
<manifest> | Gabungkan turunan saja | Hanya ada satu per file |
<meta-data> | Gabungkan | Atribut android:name |
<path-permission> | Gabungkan | Hanya ada satu per <provider> |
<permission-group> | Gabungkan | Atribut android:name |
<permission> | Gabungkan | Atribut android:name |
<permission-tree> | Gabungkan | Atribut android:name |
<provider> | Gabungkan | Atribut android:name |
<receiver> | Gabungkan | Atribut android:name |
<screen> | Gabungkan | Atribut android:screenSize |
<service> | Gabungkan | Atribut android:name |
<supports-gl-texture> | Gabungkan | Atribut android:name |
<supports-screen> | Gabungkan | Hanya ada satu per <manifest> |
<uses-configuration> | Gabungkan | Hanya ada satu per <manifest> |
<uses-feature> | Gabungkan | Atribut android:name (jika tidak ada, berarti atribut android:glEsVersion) |
<uses-library> | Gabungkan | Atribut android:name |
<uses-permission> | Gabungkan | Atribut android:name |
<uses-sdk> | Gabungkan | Hanya ada satu per <manifest> |
| Elemen khusus | Gabungkan | Tidak ada pencocokan; ini tidak dikenali oleh alat bantu penggabung, sehingga selalu disertakan dalam manifes gabungan |
Komentar
Posting Komentar