多模块依赖打包aar/jar的方法以及遇到的坑

内容介绍

  1. 多模块依赖打包成aar方法介绍
  2. 多模块依赖打包成jar的方法介绍
  3. 使用过程中踩到的一些坑
  4. 总结

1. 多模块依赖打包成aar方法介绍

在你工程里某个模块添加的插件为library的时候,编译生成的产物就是aar包(其实就是个压缩包里面装了资源文件跟jar还有些配置文件,直接解压就能看到)。
在studio编aar的时候,只会将你的当前模块的内容打包,尽管你依赖了其他模块,也不会将其他模块的东西打进去(远程依赖除外,因为远程依赖指向是一个远程地址,只要指向对了,就能在使用aar的时候被找到)。

既然studio没有为我们准备打包多个模块的功能,就会有大佬去做这样的功能。下面介绍一个插件 fat-aar.gradle
插件地址:https://github.com/adwiv/android-fat-aar/blob/master/fat-aar.gradle

这个插件提供了一个新的依赖方式:embedded (嵌套)
下面介绍下使用方法:
首先在模块的build.gradle里添加插件
本地添加:apply from: ‘fat-aar.gradle’
远程添加:apply from: ‘https://raw.githubusercontent.com/adwiv/android-fat-aar/master/fat-aar.gradle

接着使用embedded 依赖其他模块
embedded project(’:modelA’)
这样打包的时候,就会帮你把embedded的模块的内容打包进去了。

这种嵌套依赖引发的问题
兼容性问题。目前fat-aar最新版本只支持到gradle 2.3.3版本。因为更高的gradle版本build的产物目录有所变更。fat-aar实现逻辑其实就是帮你把其他模块生成制build目录下*.class以及资源拷贝到需要打包的模块,然后再进行打包。所以要是产物目录变了,就会出问

2.多模块依赖打包成jar的方法介绍

jar包打包起来比aar简单得多,因为不需要到资源文件。只需要将所有class文件打包在一起就行了。而且gradle也提供有打jar的task type。所以这里使用自定义task来做。不过需要注意的是,打包需要排除部分文件,不如R文件、BuildConfig文件。

栗子:
modelB依赖了modelA,现在需要将模块modelB打包成一个jar,并且产生jar的路径为modelB文件目录下的output文件夹。

//执行顺序
//build -> deleteOldTmpDirAndJar-> copyClasses -> makeJavadoc(生成javadoc) -> makeJavadocToJar(打包javadoc) -> assembleJar

//该task作用是删除久的jar包以及久的临时文件
task deleteOldTmpDirAndJar(type: Delete, dependsOn: build) {
    println("=============== Delete old ./output ===============")
    delete './output'
    println("=============== Delete old tmpJarDir ===============")
    delete './build/tmpJarDir'
    println("=============== Delete old tmpJavaDoc ===============")
    delete './build/tmpJavaDoc'
}

//拷贝class文件
task copyClasses(type: Copy, dependsOn: deleteOldTmpDirAndJar) {
    println("=============== copyClasses ===============")
    from('../modelA/build/intermediates/classes/release')
    from('build/intermediates/classes/release')
    into('./build/tmpJarDir')
    exclude('**/R.class')
    exclude('**/BuildConfig.class')
}

//产生javadoc,有需要的同学可以保留
task makeJavadoc(type: Javadoc, dependsOn: copyClasses) {
    println("===============make Javadoc ===============")
    options.encoding = "UTF-8"
    options.charSet = 'UTF-8'
    options.setMemberLevel(JavadocMemberLevel.PUBLIC)
    source = android.sourceSets.main.java.srcDirs
    classpath += project.files('build/tmpJarDir/')
    destinationDir = reporting.file("../tmpJavaDoc/")
    exclude '**/BuildConfig.java'
    exclude '**/R.java'
    failOnError false
}

//将javadoc文件目录打成压缩包,有需要的同学可以保留
task makeJavadocToJar(type: Jar, dependsOn: makeJavadoc){
    println("=============== Javadoc To Jar ===============")
    archiveName = 'modelBJavaDoc.jar'
    from('./build/tmpJavaDoc')
    destinationDir = file('./output')
}

//将class文件打成jar包
task assembleJar(type: Jar, dependsOn: makeJavadocToJar){
    println("=============== assembleJar ===============")
    archiveName = 'modelB.jar'
    from('./build/tmpJarDir')
    destinationDir = file('./output')
    exclude('com/xxx/modelA/BuildConfig.class')
    exclude('com/xxx/modelB/BuildConfig.class')
}

3. 使用过程中踩到的一些坑

① 使用embedded的坑

如果你使用了modelB使用了embedded方式依赖了medelA。而modelC又依赖了modelB的时候。你会发现,你怎么编译modelC都会报错

Multiple dex files define Lcom/xxx/xxx/xxx

原因是在modelB build了之后fat-aar插件会帮你把modelA的build目录的class文件拷贝到了modelB 的build文件目录里面去。因为你依赖了modelA的关系,studio在编译过程中也会去modelA的build文件目录去找class文件。所以导致了modelA的build目录的class跟modelB里面的重复了。
“实际上,fat-aar的embedded其实是compile的一个封装”
在这里插入图片描述

那上面说的这个问题怎么解决呢,我这里提供一个方法供参考 。要是大家有什么更好的方法,也可以分享下。
我这边的需求是上传maven仓库的时候才用到embedded的依赖,其他情况都使用compile。所以我通过gradle执行的task来区分依赖的类型

def dependType = 'compile'
gradle.startParameter.taskNames.each({
    String taskName = it
    if(taskName.contains("uploadArchives")) { //当task是上传maven的时候使用嵌套依赖
        dependType = 'embedded'
        return
    }else{
        dependType = 'compile'
    }
})


dependencies {
    if (dependType.equals("embedded")){
        embedded project(':modelA')
    } else{
        compile project(':modelA')
    }
}
后续在使用中遇到什么坑,再补充。未完待续!

总结

使用embedded的依赖进行多模块打包aar的方式,是目前比较多人采用的一种方式。多模块打包aar并不是完全没有其他的方式,比方说使用远程依赖的方式也是可以的,不过比较麻烦。
如果大家觉得我哪里不对或者有疑问的地方,可以在评论区留意,一起交流学习。

本文参考文章:
https://www.jianshu.com/p/8f9cf6271c20

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值