赞
踩
Android通过aar方式可以把代码,资源文件等等打成一个包,提供给第三方使用或者自己使用,aar包含这所需要的依赖资源,避免了大量的模块引用,加快了编译的速度,另外在SDK开发中通常是以aar的方法或者远程依赖提供给第三方使用。下面总结下aar生成依赖的方式和应用存在的一些问题。下面举例:
app依赖library,library依赖BaseLibrary,这种情况下如果library需要生成aar提供给app使用或者提供给第三方使用,就需要合理的进行打包资源,生成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比较多的话用起来比较繁琐,这时候可以将BaseLibrary和library合并成一个aar来进行使用。如果将base-aar放入ibrary-aar直接打包生成aar会出现下面classes.jar嵌套的情况:
这种情况显然是有问题的,因此不能这样使用。下面介绍一种开源的方式:
1、使用方式
参考:https://github.com/kezong/fat-aar-android
2、集成
project/build.gradle下:
- buildscript {
- dependencies {
- classpath 'com.android.tools.build:gradle:3.4.0'
- classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
- classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
- }
- }
library/build.gradle下:
- apply plugin: 'com.kezong.fat-aar'
-
- dependencies {
-
- implementation 'androidx.appcompat:appcompat:1.2.0'
- implementation 'com.google.android.material:material:1.2.1'
- testImplementation 'junit:junit:4.+'
- androidTestImplementation 'androidx.test.ext:junit:1.1.2'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
-
- embed project(':BaseLibrary')
- }
3、使用
./gradlew library:assemble
这时候生成的library-aar即是包含base-aar的aar,即将两个aar合并成为一个,此时还是不能找到implementation或者api的依赖,如果base-aar或者library-aar中含有远程依赖,则需要重新将依赖文件拷贝到app的gradle的dependencies中去,否则会找不到类。下面可以通过embed将一个implementation或者api打入aar中,如:
- apply plugin: 'com.kezong.fat-aar'
-
- dependencies {
-
- implementation 'androidx.appcompat:appcompat:1.2.0'
- implementation 'com.google.android.material:material:1.2.1'
- testImplementation 'junit:junit:4.+'
- androidTestImplementation 'androidx.test.ext:junit:1.1.2'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
-
- embed project(':BaseLibrary')
- embed 'com.google.code.gson:gson:2.8.4'
- embed 'com.github.bumptech.glide:glide:4.11.0'
- }
生成的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(),如下:
- buildscript {
- repositories {
- mavenLocal()
- google()
- jcenter()
- }
- dependencies {
- classpath "com.android.tools.build:gradle:3.4.0"
- }
- }
2、app/build.gradle
- apply plugin: 'maven'
-
- uploadArchives {
- configuration = configurations.archives
- repositories {
- mavenDeployer {
- //这里必须要file://localhost/,后面的地址换成你本地的绝对路径,下面是mac的路径
- repository(url: "file://localhost/" + "/Users/xxx/Desktop/aar")
- pom.project {
- version '1.0.0'
- artifactId 'library-demo'
- groupId 'com.test.demo'
- packaging 'aar'
- description '测试aar本地仓库'
- }
- }
- }
- }
参数定义如下:
3、执行
./gradlew uploadArchives
4、结果
5、使用
在项目最外层build.gradle 文件中添加如下代码
- allprojects {
- repositories {
- google()
- jcenter()
- //注意:路径与之前生成路径保持一致,需要加上file://,下面是mac地址
- maven{ url "file:///Users/xxx/Desktop/aar"}
- //或者,二选一
- maven {
- url "file://${new File(project.rootProject.rootDir, 'aar').getAbsolutePath()}"
- }
- }
- }
之后添加依赖:
implementation 'com.test.demo:library-demo:1.0.0'
重新编译一下即可使用。
1、jcenter仓库配置
本地maven仓库虽然解决了依赖问题,但是之只能在本地使用,但是在开发中使用最多的全球三大仓库是mavenCentral()、jcenter()、google()仓库,下面以jcenter仓库为例,介绍本地library的上传。
1.1、注册Jcenter
备注:网上很多帖子说这块需要注册个人版的,直接点进去是企业版的,没法发布,我在最新的官方上没遇到这种情况,直接点进去注册就行。
备注:另外网上很多帖子说注册需要国外邮箱才行,国内的不行,比如说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下面添加:
- buildscript {
-
- dependencies {
-
- classpath 'com.android.tools.build:gradle:3.4.0'
-
- classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
- classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
- }
- }
2.2、library/build.gradle配置
在library/build.gradle最下面配置如下:
配置好在使用的时候即可:
implementation 'com.test.demo:payLib:1.0.0'
这样,每个模块需要提交的jcenter的时候就配置上面几行代码,方便灵活,下面介绍jcenter.gradle的内容。
2.3、jcenter.gradle
jcenter.gradle位于项目的根目录,包括三大内容:
首先需要使用引入的插件:
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'
(1)完成maven相关文件的生成与打包
- //项目在github主页地址
- def siteUrl = 'https://github.com/xxx/xxx'
- //Git仓库的地址
- def gitUrl = 'https://github.com/xxx/xxx'.git'
-
- //这块的内容就是implementation 'com.test.demo:payLib:1.0.0'的com.test.demo,要使用啥改成啥
- group = 'com.test.demo'
- //项目引用的版本号
- version = project.versionName
-
- install {
- repositories.mavenInstaller {
- // 生成pom.xml和参数
- pom {
- project {
- packaging 'aar'
- //可选,项目名称。
- name project.libraryName
- //可选,项目描述。
- description project.libraryDesc
- // 项目主页,这里是引用上面定义好。
- url siteUrl
- // 软件开源协议,现在一般都是Apache License2.0
- licenses {
- license {
- name 'The Apache Software License, Version 2.0'
- url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
- }
- }
- //填写开发者基本信息,复制我的,这里需要修改。
- developers {
- developer {
- //开发者的个人信息
- id 'zhangsan'
- name 'zhangsan'
- email 'zhangsan@qq.com'
- }
- }
-
- // SCM
- scm {
- // Git仓库地址.
- connection gitUrl
- // Git仓库地址。
- developerConnection gitUrl
- // 项目主页。
- url siteUrl
- }
- }
- }
- }
- }
(2)生成javadoc.jar和source.jar
- // 生成jar包的task
- task sourcesJar(type: Jar) {
- from android.sourceSets.main.java.srcDirs
- classifier = 'sources'
- }
-
- // 生成jarDoc的task
- task javadoc(type: Javadoc) {
- source = android.sourceSets.main.java.srcDirs
- classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
- // destinationDir = file("../javadoc/")
- failOnError false // 忽略注释语法错误,如果用jdk1.8你的注释写的不规范就编译不过。
- }
-
- // 生成javaDoc的jar
- task javadocJar(type: Jar, dependsOn: javadoc) {
- classifier = 'javadoc'
- from javadoc.destinationDir
- }
- artifacts {
- archives javadocJar
- archives sourcesJar
- }
这块没啥好讲的,直接复制即可。
(3)文件的打包上传到bintray.com
- // 这里是读取Bintray相关的信息,不要把帐号密码的信息直接写在这里,写在local.properties中,这里动态读取。
- Properties properties = new Properties()
- properties.load(project.rootProject.file('local.properties').newDataInputStream())
- bintray {
- // Bintray的用户名。
- user = properties.getProperty("bintray.user")
- // Bintray刚才保存的ApiKey。
- key = properties.getProperty("bintray.apikey")
- configurations = ['archives']
- pkg {
- //id
- userOrg = user
- //Repository名字 需要自己在bintray网站上先添加
- repo = properties.getProperty("bintray.rep")
- //发布到JCenter上的项目名字
- name = project.libraryName
- //项目描述
- desc = project.libraryDesc
- websiteUrl = siteUrl
- vcsUrl = gitUrl
- licenses = ["Apache-2.0"]
- // 是否是公开项目。
- publish = true
- }
- }
-
- //如果你的项目里面有中文注释的话,必须将格式设置为UTF-8,不然会出现乱码
- javadoc {
- options {
- encoding "UTF-8"
- charSet 'UTF-8'
- author true
- version true
- links "http://docs.oracle.com/javase/7/docs/api"
- }
- }
为了控制权限,不要把帐号密码的信息直接写在这里,写在local.properties中,这里动态读取。包括用户名、密码、仓库名称。
2.4、local.properties
3、推送到jcenter
项目右上角gradle,点击bintrayUpload就上传上去了。
上传完成之后,打开https://bintray.com/,就会看到之前仓库新建的内容:
点开刚刚提交项目的主页,点击右下角的添加到jcenter按钮,填写信息,也可以不填:
提交之后大概40分钟左右就通过了,不通过的话也会收到邮件的说明不通过原因,修改后再次提交即可。
注意事项:
Jcenter提交的maven仓库代码必须开源,私有的,本地的,内部的,别人访问不到的等等代码仓库无法通过提交审核,如果不能开源的aar库,需要使用其他仓库,mavenCentral理论上也需要开源项目才能上传,但是可以通过添加许可证、开源协议等的方式上传非开源的依赖库,这个过程比较漫长和繁琐,另外开源项目mavenCentral相比Jcenter也不容易,所以还是推荐Jcenter方法,不开源的项目内部搭建私有仓库或者提供arr包也可以解决问题。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。