当前位置:   article > 正文

Android aar打包总结

android aar

Android通过aar方式可以把代码,资源文件等等打成一个包,提供给第三方使用或者自己使用,aar包含这所需要的依赖资源,避免了大量的模块引用,加快了编译的速度,另外在SDK开发中通常是以aar的方法或者远程依赖提供给第三方使用。下面总结下aar生成依赖的方式和应用存在的一些问题。下面举例:

app依赖library,library依赖BaseLibrary,这种情况下如果library需要生成aar提供给app使用或者提供给第三方使用,就需要合理的进行打包资源,生成aar,下面介绍集中常用的方式:

一、分模块打包aar

1、生成aar

这种方式首先对BaseLibrary打包,生成一个base-aar,,然后在对library打包生成library-aar,把两个aar都集成到app里面进行使用。通过如下命令:

 ./gradlew BaseLibrary:assemble

./gradlew library:assemble

生成aar,然后在对应的build/outputs/aar文件夹下找到对应的文件。将两个aar放在app/libs下,在对应的gradle中添加:

 implementation files('libs/base.aar')
 implementation files('libs/library.aar')

重新编译即可。

2、注意事项

通过这种方式可以将jar包打进去到aar,但是对于implementation或者api的依赖则无效,如果base-aar中含有远程依赖,则需要重新将依赖文件拷贝到app的gradle的dependencies中去,否则会找不到类。

二、整体打包aar

对于第一种方式的不足是如果aar比较多的话用起来比较繁琐,这时候可以将BaseLibrary和library合并成一个aar来进行使用。如果将base-aar放入ibrary-aar直接打包生成aar会出现下面classes.jar嵌套的情况:

这种情况显然是有问题的,因此不能这样使用。下面介绍一种开源的方式:

1、使用方式

参考:https://github.com/kezong/fat-aar-android

2、集成

project/build.gradle下:

  1. buildscript {
  2. dependencies {
  3. classpath 'com.android.tools.build:gradle:3.4.0'
  4. classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
  5. classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
  6. }
  7. }

library/build.gradle下:

  1. apply plugin: 'com.kezong.fat-aar'
  2. dependencies {
  3. implementation 'androidx.appcompat:appcompat:1.2.0'
  4. implementation 'com.google.android.material:material:1.2.1'
  5. testImplementation 'junit:junit:4.+'
  6. androidTestImplementation 'androidx.test.ext:junit:1.1.2'
  7. androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
  8. embed project(':BaseLibrary')
  9. }

3、使用

./gradlew library:assemble

这时候生成的library-aar即是包含base-aar的aar,即将两个aar合并成为一个,此时还是不能找到implementation或者api的依赖,如果base-aar或者library-aar中含有远程依赖,则需要重新将依赖文件拷贝到app的gradle的dependencies中去,否则会找不到类。下面可以通过embed将一个implementation或者api打入aar中,如:

  1. apply plugin: 'com.kezong.fat-aar'
  2. dependencies {
  3. implementation 'androidx.appcompat:appcompat:1.2.0'
  4. implementation 'com.google.android.material:material:1.2.1'
  5. testImplementation 'junit:junit:4.+'
  6. androidTestImplementation 'androidx.test.ext:junit:1.1.2'
  7. androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
  8. embed project(':BaseLibrary')
  9. embed 'com.google.code.gson:gson:2.8.4'
  10. embed 'com.github.bumptech.glide:glide:4.11.0'
  11. }

生成的aar包中就包含gons和glide的源码了,如下:

4、注意事项

尽管这种方式很便捷的能将implementation或者api的依赖合并为一个aar,但是还是存在很多兼容性问题,导致编译失败,常见的如下:

(1)资源冲突

假如BaseLibrary和library有个values/strings的内容:

<string cancel">取消</string>

或者values/colors的内容:

<color name="c_1A1B1F">#1A1B1F</color>

这时候就会引起资源冲突,解决方法是保证每个library的资源名称不一样。

(2)依赖冲突

假如第三方的库和aar或者本地依赖未打成aar的库有多个不同版本的gson,这时候需要exclude多余的gson,保证只能使用一个,这样如果引用的比较多或者比较深的话很难完全找到,用起来也很麻烦。

其他的问题请参考:https://www.jianshu.com/p/8f9cf6271c20?tdsourcetag=s_pcqq_aiomsg

三、使用本地仓库

以上两种方式都是生成本地aar方式,这种方式不能够理想的打包进去implementation的依赖,maven方式则可以不用担心这种情况,生成的maven仓库的pom文件则包含了依赖的所以信息,当使用生成的仓库使用,则可以自动的拉取下来所需的aar文件和相关依赖。

1、project/build.gradle

buildscript /repositories里面添加mavenLocal(),如下:

  1. buildscript {
  2. repositories {
  3. mavenLocal()
  4. google()
  5. jcenter()
  6. }
  7. dependencies {
  8. classpath "com.android.tools.build:gradle:3.4.0"
  9. }
  10. }

2、app/build.gradle

  1. apply plugin: 'maven'
  2. uploadArchives {
  3. configuration = configurations.archives
  4. repositories {
  5. mavenDeployer {
  6. //这里必须要file://localhost/,后面的地址换成你本地的绝对路径,下面是mac的路径
  7. repository(url: "file://localhost/" + "/Users/xxx/Desktop/aar")
  8. pom.project {
  9. version '1.0.0'
  10. artifactId 'library-demo'
  11. groupId 'com.test.demo'
  12. packaging 'aar'
  13. description '测试aar本地仓库'
  14. }
  15. }
  16. }
  17. }

参数定义如下:

  • repository url 路径可自定义
  • version   版本
  • artifactId 名称
  • groupId  包名
  • packaging 类型
  • description 描述

3、执行 

./gradlew uploadArchives  

4、结果

5、使用

在项目最外层build.gradle 文件中添加如下代码

  1. allprojects {
  2. repositories {
  3. google()
  4. jcenter()
  5. //注意:路径与之前生成路径保持一致,需要加上file://,下面是mac地址
  6. maven{ url "file:///Users/xxx/Desktop/aar"}
  7. //或者,二选一
  8. maven {
  9. url "file://${new File(project.rootProject.rootDir, 'aar').getAbsolutePath()}"
  10. }
  11. }
  12. }

之后添加依赖:

implementation 'com.test.demo:library-demo:1.0.0'

重新编译一下即可使用。

四、使用jcenter仓库

1、jcenter仓库配置

本地maven仓库虽然解决了依赖问题,但是之只能在本地使用,但是在开发中使用最多的全球三大仓库是mavenCentral()、jcenter()、google()仓库,下面以jcenter仓库为例,介绍本地library的上传。

1.1、注册Jcenter

https://bintray.com/

备注:网上很多帖子说这块需要注册个人版的,直接点进去是企业版的,没法发布,我在最新的官方上没遇到这种情况,直接点进去注册就行。

备注:另外网上很多帖子说注册需要国外邮箱才行,国内的不行,比如说google邮箱,我用的是公司的企业邮箱注册,一切顺利。

1.2、新建仓库

这样就注册完成!返回首页,下面会多一个仓库名称,就是你建立的仓库:

点进去啥也没有:

网上有的帖子说还需要Add New Package,这个步骤其实不用,到此仓库就建立完成了,准备工作已经做好了。

2、gralde环境配置

2.1、插件配置

gradle推送到jcenter需要使用两个插件:

classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'

在projct/build.gradle下面添加:

  1. buildscript {
  2. dependencies {
  3. classpath 'com.android.tools.build:gradle:3.4.0'
  4. classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
  5. classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
  6. }
  7. }

2.2、library/build.gradle配置

在library/build.gradle最下面配置如下:

配置好在使用的时候即可:

implementation 'com.test.demo:payLib:1.0.0'

  • com.test.demo:给个库的配置一样,因此在jcenter中写死了,去每次重复的编写。
  • payLib:就是上面libraryName的名称,一般和模块名称一致。
  • 1.0.0:版本号,每次提交到jcenter的时候必须升级版本号,否则提交失败。

这样,每个模块需要提交的jcenter的时候就配置上面几行代码,方便灵活,下面介绍jcenter.gradle的内容。

2.3、jcenter.gradle

jcenter.gradle位于项目的根目录,包括三大内容:

  1. 完成maven相关文件的生成与打包。
  2. 生成javadoc.jar和source.jar。
  3. 文件的打包上传到bintray.com。

首先需要使用引入的插件:

apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'

(1)完成maven相关文件的生成与打包

  1. //项目在github主页地址
  2. def siteUrl = 'https://github.com/xxx/xxx'
  3. //Git仓库的地址
  4. def gitUrl = 'https://github.com/xxx/xxx'.git'
  5. //这块的内容就是implementation 'com.test.demo:payLib:1.0.0'的com.test.demo,要使用啥改成啥
  6. group = 'com.test.demo'
  7. //项目引用的版本号
  8. version = project.versionName
  9. install {
  10. repositories.mavenInstaller {
  11. // 生成pom.xml和参数
  12. pom {
  13. project {
  14. packaging 'aar'
  15. //可选,项目名称。
  16. name project.libraryName
  17. //可选,项目描述。
  18. description project.libraryDesc
  19. // 项目主页,这里是引用上面定义好。
  20. url siteUrl
  21. // 软件开源协议,现在一般都是Apache License2.0
  22. licenses {
  23. license {
  24. name 'The Apache Software License, Version 2.0'
  25. url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
  26. }
  27. }
  28. //填写开发者基本信息,复制我的,这里需要修改。
  29. developers {
  30. developer {
  31. //开发者的个人信息
  32. id 'zhangsan'
  33. name 'zhangsan'
  34. email 'zhangsan@qq.com'
  35. }
  36. }
  37. // SCM
  38. scm {
  39. // Git仓库地址.
  40. connection gitUrl
  41. // Git仓库地址。
  42. developerConnection gitUrl
  43. // 项目主页。
  44. url siteUrl
  45. }
  46. }
  47. }
  48. }
  49. }

(2)生成javadoc.jar和source.jar

  1. // 生成jar包的task
  2. task sourcesJar(type: Jar) {
  3. from android.sourceSets.main.java.srcDirs
  4. classifier = 'sources'
  5. }
  6. // 生成jarDoc的task
  7. task javadoc(type: Javadoc) {
  8. source = android.sourceSets.main.java.srcDirs
  9. classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
  10. // destinationDir = file("../javadoc/")
  11. failOnError false // 忽略注释语法错误,如果用jdk1.8你的注释写的不规范就编译不过。
  12. }
  13. // 生成javaDoc的jar
  14. task javadocJar(type: Jar, dependsOn: javadoc) {
  15. classifier = 'javadoc'
  16. from javadoc.destinationDir
  17. }
  18. artifacts {
  19. archives javadocJar
  20. archives sourcesJar
  21. }

这块没啥好讲的,直接复制即可。

(3)文件的打包上传到bintray.com

  1. // 这里是读取Bintray相关的信息,不要把帐号密码的信息直接写在这里,写在local.properties中,这里动态读取。
  2. Properties properties = new Properties()
  3. properties.load(project.rootProject.file('local.properties').newDataInputStream())
  4. bintray {
  5. // Bintray的用户名。
  6. user = properties.getProperty("bintray.user")
  7. // Bintray刚才保存的ApiKey。
  8. key = properties.getProperty("bintray.apikey")
  9. configurations = ['archives']
  10. pkg {
  11. //id
  12. userOrg = user
  13. //Repository名字 需要自己在bintray网站上先添加
  14. repo = properties.getProperty("bintray.rep")
  15. //发布到JCenter上的项目名字
  16. name = project.libraryName
  17. //项目描述
  18. desc = project.libraryDesc
  19. websiteUrl = siteUrl
  20. vcsUrl = gitUrl
  21. licenses = ["Apache-2.0"]
  22. // 是否是公开项目。
  23. publish = true
  24. }
  25. }
  26. //如果你的项目里面有中文注释的话,必须将格式设置为UTF-8,不然会出现乱码
  27. javadoc {
  28. options {
  29. encoding "UTF-8"
  30. charSet 'UTF-8'
  31. author true
  32. version true
  33. links "http://docs.oracle.com/javase/7/docs/api"
  34. }
  35. }

为了控制权限,不要把帐号密码的信息直接写在这里,写在local.properties中,这里动态读取。包括用户名、密码、仓库名称。

  1. 用户名:就是登录jcenter的用户名。
  2. 仓库名称:就是上上面创建的仓库名称。
  3. 密码:点击头像,选择Edit Your Profile,出现

2.4、local.properties

  • bintray.rep=你的仓库名称
  • bintray.apikey=获取到的key
  • bintray.user=你的登录名称

3、推送到jcenter

项目右上角gradle,点击bintrayUpload就上传上去了。

上传完成之后,打开https://bintray.com/,就会看到之前仓库新建的内容:

点开刚刚提交项目的主页,点击右下角的添加到jcenter按钮,填写信息,也可以不填:

提交之后大概40分钟左右就通过了,不通过的话也会收到邮件的说明不通过原因,修改后再次提交即可。

注意事项:

Jcenter提交的maven仓库代码必须开源,私有的,本地的,内部的,别人访问不到的等等代码仓库无法通过提交审核,如果不能开源的aar库,需要使用其他仓库,mavenCentral理论上也需要开源项目才能上传,但是可以通过添加许可证、开源协议等的方式上传非开源的依赖库,这个过程比较漫长和繁琐,另外开源项目mavenCentral相比Jcenter也不容易,所以还是推荐Jcenter方法,不开源的项目内部搭建私有仓库或者提供arr包也可以解决问题。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/331595
推荐阅读
相关标签
  

闽ICP备14008679号