android不但可以引用jar包,而且还有自己的特殊jar包–aar压缩包。
一、aar的生成方法
1、直接make project生成aar
在生成AAR的时候,先创建一个Library的Module,然后Build –> Make project(或者gradle clean build)就可以在build/outputs/aar下生成xxx.aar文件。
以上方法会有个问题:依赖的第三方比如dependencies或者jar包没有被继承到xx.aar文件压缩包下。这时候需要如下方法:
2、使用maven构建生成aar
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
repository(url:"e://extras/android/m2repository/")
pom.version = '1.0-SNAPSHOT' //aar的版本号
pom.groupId = 'com.chinaso.lib' //aar的包名
pom.artifactId = 'chinasolibs' //aar的名称
}
}
}
生成aar的命令:
gradle uploadArchives
执行:gradle uploadArchives时出现了异常:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':chinasosdk:uploadArchives'.
> Could not publish configuration 'archives'
> Failed to deploy artifacts/metadata: No connector available to access repository
remote (e://extras/android/m2repository/) of type default using the available factorie
s WagonRepositoryConnectorFactory
解决办法:
因为地址改成:repository(url:”file://e://extras/android/m2repository/”)
就可以在E盘下看到aar文件了。
二、aar的使用
1、复制aar包到module中
把上面生成的aar包copy到需要的Module下,然后在该Module的build.gradle添加:
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
compile(name: '生成的aar(不要后缀)', ext: 'aar')
。。。
2、远程依赖的方法使用aar
和一般jar的远程依赖一样,在module项目的build.gradle中添加:
dependencies {
compile 'cn.jesse.android:datetimepicker:1.0.2'
}
远程依赖的aar需要使用远程仓库,可以自己使用nexus搭建自己的私有本地仓库,暂时没有实现。
可以参考.
三、简单介绍构建工具gradle
1、构建工具的简介
Ant已经销声匿迹,而Maven也日薄西山,gradle已经广受欢迎。
gradle是一个工具,同时它也是一个编程框架,因此就必须要了解它的设计规则:
Gradle中,每一个待编译的工程都叫一个Project。每一个Project在构建的时候都包含一系列的Task。比如一个Android APK的编译可能包含:Java源码编译Task、资源编译Task、JNI编译Task、lint检查Task、打包生成APK的Task、签名Task等。
一个Project到底包含多少个Task,其实是由编译脚本指定的插件决定。插件是什么呢?插件就是用来定义Task,并具体执行这些Task的东西。
刚才说了,Gradle是一个框架,作为框架,它负责定义流程和规则。而具体的编译工作则是通过插件的方式来完成的。比如编译Java有Java插件,编译Groovy有Groovy插件,编译Android APP有Android APP插件,编译Android Library有Android Library插件
好了。到现在为止,你知道Gradle中每一个待编译的工程都是一个Project,一个具体的编译过程是由一个一个的Task来定义和执行的。(主要这里的Project和Eclipse下的Project类似,但严格意义上来说不是Android Studio上的Project,而是AS上的module。这里只要知道Project就是AS上的Module即可)
创建一次Android Studio的android项目可以包含几个project,如果要独立编译他们,需要cd到相应项目的目录下,然后gradle xxxx。这很没法。
gradle基于groovy,groovy又 基于java,所以gradle执行的时候和groovy一样,会把脚本转换成java对象。
Maven是Apache开发的一个工具,提供了用于贡献library的文件服务器,总的来说,只有两个标准的Android library文件服务器:jcenter和Maven Central。
jcenter是一个由bintray.com维护的Maven仓库,地址:http://jcenter.bintray.com/可以看到整个仓库的内容。我们在项目的build.gradle 文件中如下定义仓库,就能使用jcenter了:
allprojects {
repositories {
jcenter()
}
}
Maven central则是有sonatype.org维护的maven仓库,可以在官网上看到整个仓库的内容。不管是jcenter还是Maven Central都是Maven仓库。定义如下就能使用Maven仓库:
allprojects {
repositories {
mavenCentral()
}
}
虽然jcenter和Maven Central 都是标准的 android library仓库,但是它们维护在完全不同的服务器上,由不同的人提供内容,两者之间毫无关系。在jcenter上有的可能 Maven Central 上没有,反之亦然。除了Maven仓库外,还有lvy仓库
但是Maven Central的最大问题是对开发者不够友好。上传library异常困难。上传上去的开发者都是某种程度的极客。同时还因为诸如安全方面的其他原因,Android Studio团队决定把默认的仓库替换成jcenter。正如你看到的,一旦使用最新版本的Android Studio创建一个项目,jcenter()自动被定义,而不是mavenCentral()。
有许多将Maven Central替换成jcenter的理由,下面是几个主要的原因。
- jcenter通过CDN发送library,开发者可以享受到更快的下载体验。
- jcenter是全世界最大的Java仓库,因此在Maven Central 上有的,在jcenter上也极有可能有。换句话说jcenter是Maven Central的超集。
- 上传library到仓库很简单,不需要像在 Maven Central上做很多复杂的事情
- 友好的用户界面
2、gradle是如何从仓库上获取一个library的
一般来说,我们需要知道library的字符串形式,包括3部分:
GROUP_ID:ARTIFACT_ID:VERSION
比如:
compile 'com.squareup.okhttp:okhttp:2.4.0'
GROUP_ID定义了library的group。有可能在同样的上下文中存在多个不同功能的library。如果library具有相同的group,那么它们将共享一个GROUP_ID。通常我们以开发者包名紧跟着library的group名称来命名,比如com.squareup.picasso。然后ARTIFACT_ID中是library的真实名称。至于VERSION,就是版本号而已,虽然可以是任意文字,但是我建议设置为x.y.z的形式,如果喜欢还可以加上beta这样的后缀。
那么在添加了上面的依赖之后会发生什么呢?简单。Gradle会询问Maven仓库服务器这个library是否存在,如果是,gradle会获得请求library的路径,一般这个路径都是这样的形式:
GROUP_ID/ARTIFACT_ID/VERSION_ID
比如可以在http://jcenter.bintray.com/com/squareup/okhttp/okhttp/2.4.0下获得com.squareup.okhttp:okhttp:2.4.0的library文件。然后Android Studio 将下载这些文件到我们的电脑上,与我们的项目一起编译。整个过程就是这么简单,一点都不复杂。
3、gradle出错的解决
类似下面的failed to resolve:
解决方法一:(失败)
Settings->Build,Execution,Deployment->Gradle下Project-level settings,选择
Use default gradle wrapper(recommend),同时设置gradle->wrapper->gradle-wrapper.properties最后一行:
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
如果在目录下:
C:\Users\Administrator.gradle\wrapper\dists\gradle-3.3-all\55gk2rcmfc6p2dg9u9ohc3hw9
可以看到gradle-3.3-all.zip.lck和gradle-3.3-all.zip.part(两个文件不能都是0kb),表示下载成功。
然后点击Sync Project with Gradle Files,失败。
如果目录下没有下载成功,可以到gradle官网下载gradle-3.3-all.zip放到gradle-wrapper目录下,然后设置gradle->wrapper->gradler-wrapper.properties最后一行:
distributionUrl=gradle-3.3-all.zip
解决方法二:(失败)
Settings->Build,Execution,Deployment->Gradle下Project-level settings,选择
Use local gradle distribution,然后gradle home:选择已有的gradle-3.3或者别的版本。依然不行。
解决方法三:(失败)
在module下的build.gradle文件中,buildToolsVersion/compileSdkVersion/targetSdkVersion版本设置高一点。
虽然以上方法失败了,但都是配置gradle的方法。
应该是网络的问题,使用360断网急救箱诊断一下就可以了,可能与我使用astrill有关。
3、gradle和gradlew
gradle和gradlew都可以打包,使用功能上没区别。可以简单理解成gradlew是android为了使用gradle构建而做了一层封装,我们在使用Android Studio创建项目的时候会自动帮我们在项目的根目录下创建gradle文件夹,里面的文件夹wrapper包含:gradle-wrapper.jar和gradle-wrapper.properties。调用gradlew命令的时候,最终也是调用gradle的命令。在创建好的项目中,在终端输入./gradlew –version就可以看到版本号,如果是第一次使用gradlew,还会下载包装里定义好的gradle版本。使用gradle是本地的gradle,需要自己下载安装。
使用gradle wrapper是gradle官方推荐的build方式。使用gralde wrapper的一个好处就是每个项目可以依赖不同版本的gradle,构建的时候gradle wrapper会帮你自动下载所依赖的版本的gradle。而如果你使用gradle build的话,同时你又有多个项目使用不同版本的gradle,那就需要你手动在自己的机器上配置多个版本的gradle,然后配置好环境变量后就可以使用了,也是比较麻烦。但是当我们把项目分享给电脑上没有gradle的人时,问题就来了。或者我们在一个没有装gradle的server上build的时候也会出现同样的问题。
所以基于此,gradle系统引入了我们今天的主角-gralde wrapper: 一个gradle的封装体。有了gradle wrapper,即便你的机器上没有安装gradle,也可以执行gradle的构建工作了。
需要使用gradle wrapper的时候,我们就直接在项目根目录下直接执行gradlew(gradle wrapper的简写), 使用gradlew的方式和gradle一模一样, 例如通过gradlew tasks来查看所有的任务。事实上,执行gradlew命令的时候,gradlew会委托gradle命令来做相应的事情,所以gradlew真的只是一个壳而已。
不过需要说明的是,假如你是用android studio新建的项目,它会自动为新建的工程添加wrapper。也就是你就不必自己再去创建gradle wrapper了,直接在命令行或者你的编译脚本中使用就好了。