在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称(OpenSource Name):yanbober/android-build-filter-gradle-plugin开源软件地址(OpenSource Url):https://github.com/yanbober/android-build-filter-gradle-plugin开源编程语言(OpenSource Language):Groovy 92.2%开源软件介绍(OpenSource Introduction):android-build-filter-gradle-plugin一个小众需求下移除 Android 构建中 Jar 包、AAR 包、构建冗余 class 文件的 Gradle 插件。 配置在相应 gradle 文件添加如下仓库。 buildscript {
repositories {
maven { url 'https://jitpack.io' }
}
}
dependencies {
classpath 'com.github.yanbober:android-build-filter-gradle-plugin:1.0.1'
}
}
apply plugin: 'buildfilter'
//或者
apply plugin: 'android.build.filter.gradle' 使用将想要移除的 class 文件添加到对应配置中,如下: apply plugin: 'buildfilter'
buildClassFilter {
sourceExcludes = [
'YOUR CLASS', '**/BuildConfig*'
]
jarExcludes = [ 'cn/sina/sdk/BuildConfig.class' ]
} 其中 class 全限定描述名支持标准正则匹配。 sourceExcludes 中配置你项目中源码生成或者 IDE 自动生成的 class 文件(譬如 BuildConfig)。 jarExcludes 中配置你项目依赖的 aar 或者 jar 包中你想移除的 class 文件。 校验与追踪按照如上配置后进行项目构建编译,编译后你可以在你配置 buildClassFilter 的模块的对应构建输出目录中找到校验文件。默认输出为当前 module 下 build 目录,你可以在 build/buildClassFilter/ 目录下找到 build-class-filter-report.md 文件。 build-class-filter-report.md 文件格式如下: ## Report gradle project is demolib1.
//你在 gradle 配置的删除源码生成的 class 正则列表
## SourceExcludes config is:
cn/yan/gradle/plugin/BuildConfig.class
//依据正则在打包前被删掉的 class 列表
## SourceExcludes remove file is:
/home/yan/github/android-build-filter-gradle-plugin/demolib1/build/intermediates/classes/debug/cn/yan/gradle/plugin/BuildConfig.class
//你在 gradle 配置的删除 jar 或者 aar 中的 class 正则列表
## JarExcludes config is:
//依据正则在打包前被删掉的 class 列表
## JarExcludes remove file is:
应用场景
注意
拓展知识与该插件类似的其实还有许多其他 android 构建相关的常见棘手问题(比较多见的都是 duplicate xxx 问题),所以既然想说明该插件的用处则就顺带提下相关其他知识。 1 自定义过滤参与构建的源码Android Gradle 插件提供的常用构建源码配置 extension 如下: //执行 gradlew sourceSets 查看构建源码
android {
...
sourceSets {
main {
//设置参与构建java源文件
AndroidSourceDirectorySet java
//设置参与构建aidl源文件
AndroidSourceDirectorySet aidl
//设置参与构建assets源文件
AndroidSourceDirectorySet assets
The Android Assets directory for this source set.
//设置参与构建jni源文件
AndroidSourceDirectorySet jni
//设置参与构建jni lib源文件
AndroidSourceDirectorySet jniLibs
//设置参与构建清单源文件
AndroidSourceFile manifest
//设置参与构建renderscript源文件
AndroidSourceDirectorySet renderscript
//设置参与构建res源文件
AndroidSourceDirectorySet res
//设置参与构建的 java resource资源源文件
AndroidSourceDirectorySet resources
//其他属性
......
}
//......
androidTest {
...
}
}
} 如上列出了参与 apk 构建的源码主要配置项,你可以发现很多配置想都是 AndroidSourceDirectorySet 类型的,而 AndroidSourceDirectorySet 是 PatternFilterable 接口的子接口,所以这些类型的配置项都支持如下列表方法:
从上面方法名字和 Groovy 语法就能看出我们对于构建源码完全可以自己决定哪些参与构建,哪些不参与构建。 譬如我们不想让模块的 BuildConfig 类参与构建(BuildConfig 是构建自动生成的),如下写法: android {
sourceSets {
main {
java.exclude("cn/yan/gradle/plugin/BuildConfig.java")
}
}
} 2 自定义过滤打包到 APK 的文件除了从源头上自定义构建源文件外还可以在最终打包(听清楚,是最终)时指定哪些文件不添加到最终的压缩包(.apk)中。 packagingOptions 官方默认的配置如下:
我们构建发生这一类冲突时可以通过此类操作解决,譬如: packagingOptions {
pickFirsts = ['**/libTest.so']
merges = ['YOUR FILE']
//譬如一个jar中包含同包名AndroidManifest.xml然后被我们引用就会报AndroidManifest错误,可以exclude操作
excludes = ['**/classes.dex', '**/AndroidManifest.xml']
} 3 自定义 lib 参与构建依赖传递使用 Gradle 我们常见的 lib 依赖方式如下: //批量依赖jar包
compile fileTree(include: ['*.jar'], dir: 'libs')
//依赖一些jar包
compile files('libs/test.jar')
//依赖远程仓库aar或jar包
compile 'com.xxx:zzzz:1.0.0'
//依赖子module工程
compile project(':libmodule')
//依赖本地aar包,需要在repositories中配置flatDir存放本地aar的目录
compile(name: 'testlib', ext: 'aar') 依赖常用的基本类型有 provided、compile、compileOnly、api、implementation, provided 和 compileOnly 只编译不打包;其他类型正常情况下如果是主工程则默认会打包;如果是 lib 工程则其依赖的 jar 包默认是远程不会被打包,而本地会被打包,如果依赖的是 aar 包则默认本地远程都不会被打包进去。 一般可以通过 exclude 操作来移除构建依赖,或者通过 transitive 设置不传递依赖,如下案例:
4 自定义 lib 资源合并规则对于 res 资源想要避免冲突我们可以在构建脚本中添加 resourcePrefix 进行前缀支持,这样就可以避免。 对于 AndroidManifest.xml 的合并冲突可以采取 tools:replace 操作。 5 其他有人可能会说为什么 Java EE 等项目构建遇见多个 jar 包中包含同样包名和文件名的类且只用其中之一时构建不会报错,而 Android 中却会报错?其实原理很简单,Java EE 等项目构建两个 jar 包时会依据指定的优先级顺序合并,第二个 jar 与第一个 jar 冲突的文件会被忽略,所以在 Java EE 等项目中出现该问题时自己要明白保谁谁就得放在前面。而在 Android 中之所以构建会报错是因为 Android 报错是出现在构建的 dex 阶段,也就是将多个 class 合并 dex 时会 merge 冲突,所以对于 Android 这种冲突时要么选择移除处理,要么选择 jarjar 改名,要么还有一个我想到的骚操作就是把冲突 jar 包单独打一个 dex,然后在其他 dex 中用不同的 DexClassLoader (ClassLoader 隔离特性)加载进来反射调用,这样就避开了一个打入一个 dex 冲突的问题。 总之一句话 珍爱构建,远离本地 jar 包依赖,多用远程仓库依赖。 无论如何冒昧的修改第三方 SDK 文件是有风险的,除非你明确知道其影响面,否则还是与对方技术支持沟通最为靠谱良策。 6 Android APK 构建流程图概览图 详细图 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论