• Stars
    star
    230
  • Rank 174,053 (Top 4 %)
  • Language
    Kotlin
  • License
    Apache License 2.0
  • Created over 7 years ago
  • Updated 12 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Gradle Plugin for resolving AndroidManifest.xml merge conflicts.

Seal

Maven Central Actions Status Apache 2

English | 中文说明

Seal is a Gradle Plugin to resolve AndroidManifest.xml merge conflicts, powered by New Variant/Artifact API & Polyfill.

To be noticed, except the tag removing, any other delete/update features should always consider the "tools:replace", "tools:remove", and other official features that ManifestMerger provided as higher priority.

Functionality that Seal provided is more like the first aid to save an urgent publish that is blocked by ManifestMerger, including pre/post processors to intercept the merge flow of AndroidManifest.xml. Developers should take responsibility to report bugs to library authors(who introduced problematic Manifest), ManifestMerger(Google), AAPT2(Google), which is the true way to solve the merge issues.

Quick Start

0x01. Add the plugin to classpath:

// Option 1.
// Add `mavenCentral` to `pluginManagement{}` on `settings.gradle.kts` (or the root `build.gradle.kts`),
// and then the seal plugin id.
pluginManagement {
	repositories {
        ...
        mavenCentral()
    }
    plugins {
    	...
    	id("me.2bab.seal") version "3.3.0" apply false
    }
}

// Option 2.
// Using classic `buildscript{}` block in root build.gradle.kts.
buildscript {
    repositories {
        ...
        mavenCentral()
    }
    dependencies {
        ...
        classpath("me.2bab:seal:3.3.0")
    }
}

0x02. Apply the plugin:

// On Application's build.gradle.kts (do not use in Library project)
plugins {
    id("com.android.application")
    kotlin("android")
    // Apply this plugin
    id("me.2bab.seal")
}

0x03. Configurations

seal {

    // 0. Two cases for before merge.
    beforeMerge("Remove description attr for library input Manifest.")
        .tag("application")
        .attr("android:description")
        .deleteAttr()
    beforeMerge("Remove problematic replace attr for library input Manifest.")
        .tag("application")
        .attr("tools:replace")
        .deleteAttr()

    // Full covered cases for after merge (1-5).
    // 1. The target of this operation is too broad, please specify the attr and value if possible.
    afterMerge("Remove all uses-feature tags.")
        .tag("uses-feature")
        .deleteTag()

    // 2. The target of this operation is too broad, please specify the value if possible.
    afterMerge("Remove all custom permission tags.")
        .tag("permission")
        .attr("android:protectionLevel")
        .deleteTag()

    // 3. This is the way we recommend to delete the tag(s).
    afterMerge("Remove invalid service tag.")
        .tag("service")
        .attr("android:name")
        .value("me.xx2bab.seal.sample.library.LegacyService")
        .deleteTag()

    // You should try to use "tools:remove" or "tools:replace" instead of "deleteAttr" if possible
    // 4. To delete an attr and its value.
    afterMerge("Remove application's allowBackup attr.")
        .tag("application")
        .attr("android:allowBackup")
        .deleteAttr()

    // You should try to use "tools:remove" or "tools:replace" instead of "deleteAttr" if possible
    // 5. Also u can specify the value as part of finding params.
//    afterMerge("Remove application's allowBackup attr.")
//        .tag("application")
//        .attr("android:allowBackup")
//        .value("true")
//        .deleteAttr()

}

The configuration is separated by 3 parts:

  1. To specify the hook entry which you can select from beforeMerge(ruleName: String) or afterMerge(ruleName: String), before intercepts all merge inputs (all libraries, except the main application one), while after modifies the merged AndroidManifest.xml;
  2. To specify the search params which you can pass tag(name: String) attr(name: String) value(name: String) (currently we haven't support regex), please pass as precise as you can to locate the element
  3. To specify the delete type which you an select from deleteTag() or deleteAttr(), to be noticed, only one delete action will be executed, DO NOT call more than one deleteXXX

Common issues:

  1. Warning: AndroidManifest.xml already defines debuggable (in http://schemas.android.com/apk/res/android); using existing value in manifest.

That's because some out-of-date libraries set debuggable at AndroidManifest, but now we pass this setting from build.gradle / build.gradle.kts to AAPT.

  1. Multiple entries with same key: @android:theme=REPLACE and android:theme=REPLACE / Multiple entries with same key: @android:allowBackup=REPLACE and android:allowBackup=REPLACE.

There is a library which defined android:allowBackup=true conflicts with yours (android:allowBackup=false). You wanna to override it using tools:replace="android:allowBackup", but find that tools:replace="android:allowBackup" is also present at lib's manifest, finally the conflict shows above. (Also see this)

  1. Sometimes xmlns is wrote in application or any other tags except manifest tag, may cause aapt's concealed defect,like debuggable setting of build.gradle would not work;

Please check this link for more info.

  1. Error: tools:replace specified at line:25 for attribute android:authorities, but no new value specified

Please check this link for more info.

Compatible Specification

Polyfill is only supported & tested on latest 2 Minor versions of Android Gradle Plugin. Since 3.0.2, the publish repository has been shifted to Maven Central.

AGP Version Latest Support Version
7.2.x Maven Central
7.1.x Maven Central
7.0.x 3.1.0
4.2.x 3.0.2
3.0.x 2.0.0
2.3.x 1.1.0

(The project currently compiles with the latest version of AGP 7.0, and compiles and tests against the both AGP 7.0 and 7.1 on CI.)

Why Seal use DOM parser API

Oracle Docs: Comparing StAX to Other JAXP APIs

Since we need to support "delete tag" feature, and export outputs simply, from the link above we can know DOM is easiest one to process that. Though it consumes more CPU and memory resources, luckily most of AndroidManifest.xml are not complex and with the help of Gradle we can cache the task result if those input(s) didn't change.

License

Copyright 2017-2022 2BAB

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

More Repositories

1

KOGE

Notebook for Kotlin-oriented Gradle Essential.
183
star
2

Polyfill

An artifact repository to assist writing Gradle Plugins for Android build system.
Kotlin
83
star
3

ScratchPaper

A Gradle Plugin for adding variant/version/git-commit-id/etc information to APK launcher icon.
Kotlin
72
star
4

Extend-Android-Builds-zh

《Android 构建与架构实战》资料仓库
69
star
5

Koncat

Aggregate Kotlin Symbols from multi-modules in compile-time.
Kotlin
57
star
6

bundle-tool-gradle-plugin

A Gradle Plugin for Android BundleTool.
Kotlin
52
star
7

Android-Dynamic-Loading-Notes

Samples & Notes for Dynamic Loading Dev in Android.
Groovy
18
star
8

Caliper

A monitor & controller for Android sensitive permissions/api calls based on bytecode transformation.
Kotlin
13
star
9

Bro

Modular Kit for Android Dev.
Kotlin
10
star
10

BuildingAndroidAppManually

To show how to build an Android App manually.
Shell
8
star
11

Extend-Android-Builds-Playground-zh

《Android 构建与架构实战》配套示例代码
Shell
6
star
12

resources.arsc-demo

Some demos for resources.arsc parsing/compiling.
Java
4
star
13

Android-Worldwide-July-2022-KSP-Trick

3
star
14

DebuggableTest

A Demo Which Shows A Debuggable Bug by Google.
Java
3
star
15

transform-api-problem

Kotlin
3
star
16

SampleGradlePlugin

This Project is used for initPlugin.sh, which is A Script For Init Gradle Plugin Project.
Groovy
2
star
17

Extending-Android-Builds-Playground

A Gradle and Android Gradle Plugin Primer
Kotlin
2
star
18

Duplicator

A Gradle Plugin to generate branded APKs in seconds based on a white label one.
2
star
19

ASMDemo

ASM is an all purpose Java bytecode manipulation and analysis framework. This is a demo to show basic usage of it.
Kotlin
2
star
20

Ruler

A lite APM for Android using in staging env.
Kotlin
1
star
21

ML-Exercises

Exercises 4 Machine Learning
Java
1
star
22

KTS-BuildSrc-Composite

Kotlin
1
star
23

TokenHunter

To hunt the trend of tokens.
Python
1
star
24

Kotlin-Online-Conference-For-Chinese-Developers-2022-KSP-Use-Cases-n-Trick

https://pages.jetbrains.com/kotlin-online-conference-for-chinese-developers-2022
1
star