前言
前段时间,我在实现gradle多模块构建遇到一个问题,以前我们基本上是以jar包形式让开发者集成到工程中使用,但自从Android Studio中有了多module的概念,而我们的SDK也是分了多个模块进行构建的,但我们这里有个问题就是模块之间是相互关联的,不能针对每个模块单独打包,而每个module都会生成对应的aar,但并不会把依赖的module代码打进去,别问我为什么知道,你将aar后缀改为zip,然后反编译classes.jar就可以看到。所以我们这边就有了合并aar这样的一个需求,下面就告诉大家怎么来实现。
android-fat-aar
当时我遇到这个问题,就去github搜了一下,已经有人将合并aar的脚本开源出来了,开源地址如下:
https://github.com/adwiv/android-fat-aar
什么是aar?
什么是aar?它跟jar包有什么区别?它该怎么样使用?相信大家一定会有这些疑问。首先aar是针对Android Library而言的,你可以理解为IDE针对Android Library的打包,一个aar包含什么东西?
它的文件后缀名是.aar,它本身是一个zip文件,强制包含以下文件:
- /AndroidManifest.xml
- /classes.jar
- /res/
- /R.txt
另外,AAR文件可以包括以下可选条目中的一个或多个:
- /assets/
- /libs/name.jar
- /jni/abi_name/name.so (where abi_name is one of the Android supported ABIs)
- /proguard.txt
- /lint.jar
具体看到这里看如何创建一个Android Library:
https://developer.android.com/studio/projects/android-library.html#aar-contents
jar包跟aar包有什么区别?
jar:只包含了class文件与清单文件,不包含资源文件,如图片等所有res中的文件。
aar:包含所有资源,class以及res资源文件全部包含。
如果你只是简单实用一些类库,你可以直接使用*.jar
文件,而如果你想既想使用类库,又想实用资源,那么你就可以创建一个Android Library,使用它生成的*.aar
文件。
jar文件的使用方式我们应该比较熟悉了,将它复制到工程的libs目录下,然后在gradle中添加以下脚本:
dependencies {
compile fileTree(include: ['*.jar'], dir:'libs')
}
aar文件使用同样需要复制到libs目录下,并按照以下方式集成:
repositories {
flatDir {
dirs'libs'
}
}
dependencies {
compile(name:'your aar', ext:'aar')
}
多模块构建合并aar
这个是本文的重点,我们可以再每个module下的build/outputs/aar下找到编译生成的*.aar
文件。
步骤1:
将gradle文件'fat-aar.gradle'到你的项目目录,然后apply:
apply from: 'fat-aar.gradle'
步骤2:定义嵌入的依赖关系
你需要修改你以前依赖项,并将compile
更改为embedded
,作为你想要合并的aar。使用例子如下:
apply from: 'fat-aar.gradle'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
// Order of dependencies decide which will have precedence in case of duplicates
// during manifest / resource merger
embedded project(':librarytwo')
embedded project(':libraryone')
// We can embed android libraries from maven too
embedded 'com.adwiv.internal:librarythree:1.0.0'
compile 'com.android.support:appcompat-v7:22.2.0' //Non embedded dependency
}
通过以上的方式你可以将多个module生成的aar合成一个,大家可以新建一个demo工程来测试下
fat-aar
网友评论
> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexException: Multiple dex files define Lcom/xxx/xxx/BuildConfig;
请问楼主,按照你的方式,会出现如上错误,是什么原因?
1.Error:Could not get unknown property 'transformNative_libsWithSyncJniLibsForRelease' for project ':mainLibs' of type org.gradle.api.Project.
我看了下,提出的解决方案:transformNativeLibsWithSyncJniLibsForRelease代替 transformNative_libsWithSyncJniLibsForRelease
2.我在解决1的基础上,测试的时候,出现:
Error:FAILURE: Build failed with an exception.
* Where:
Script '/Users/huarong/AndroidStudioProjects/天威项目/封库/MyApplication/mainLibs/fat-aar.gradle' line: 219
* What went wrong:
Execution failed for task ':mainLibs:generateRJava'.
> /Users/huarong/AndroidStudioProjects/天威项目/封库/MyApplication/mainLibs/build/intermediates/exploded-aar/MyApplication/mylibrary02/unspecified/AndroidManifest.xml (No such file or directory)
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get
more log output.
这怎么解决?请问楼主有遇到这种情况吗?
应该新建module gradle里加 configurations.create("default")
artifacts.add("default", file('xxxxxxx.aar'))