为 aar 关联源代码

不知大家是否注意过,在使用 aar 时,若是本地的 aar 包,打开相关源码是反编译后的文件。而如果是引用的如 jcenter 的库,就能阅读详尽的源代码。两者的区别是什么呢?
如果大家有尝试过上传 library 到 jcenter 或 maven 就会知道,除了 aar 文件之外,还要上传相应的 sources、javadoc 以及 pom 文件,就像 ucrop 所显示的那样。gradle 在下载依赖时,也会包括 sources、javadoc 等文件,而 sources 文件正是使我们能够阅读源代码的真正原因。
那么,如何为 aar 文件添加 sources 支持呢?一种方法是添加 aar 的同时手工导入相应的 sources 文件,另一种则是将 aar、sources 上传到仓库然后通过 gradle 导入。这里说明第二种方法的使用。
由于上传到 maven、jcenter 都需要额外的步骤,为方便起见,我们搭建一个本地 Maven 仓库来讲解。如何搭建仓库可以参考 A PRIVATE MAVEN REPOSITORY FOR ANDROID IN 30 MIN,有中文翻译。后续对 build.gradle 的说明会建立在该文章的基础上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// build.gradle in root project
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0'
// 关键
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.2.0"
}
}
allprojects {
repositories {
jcenter()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// build.gradle in library project
apply plugin: 'com.android.library'
apply plugin: 'com.jfrog.artifactory'
apply plugin: 'maven-publish'
// 省略无关 andorid 配置代码
android {
...
}
dependencies {
...
}
def packageName = 'com.jeroenmols.awesomelibrary'
def libraryVersion = '1.0.0'
publishing {
publications {
aar(MavenPublication) {
groupId packageName
version libraryVersion
artifactId project.getName()
// Tell maven to prepare the generated "*.aar" file for publishing
artifact("$buildDir/outputs/aar/${project.getName()}-release.aar")
}
}
}
artifactory {
contextUrl = 'http://localhost:8081/artifactory'
publish {
repository {
// The Artifactory repository key to publish to
repoKey = 'libs-release-local'
username = "admin"
password = "password"
}
defaults {
// Tell the Artifactory Plugin which artifacts should be published to Artifactory.
publications('aar')
publishArtifacts = true
// Properties to be attached to the published artifacts.
properties = ['qa.level': 'basic', 'dev.team': 'core']
// Publish generated POM files to Artifactory (true by default)
publishPom = true
}
}
}

生成 sources.jar 文件

sources 文件实质上就是对 Android 的 java 源代码进行打包而生成 jar 包。gradle (准确来说是 Android Library Plugin) 已经为我们提供了方便的打包工具,我们简单配置一下就可以了。
在 library 的 build.gradle 中添加以下代码。
下文中的 build.gradle 如无声明,则指的是 library 下的 build.gradle 文件。

1
2
3
4
task generateSourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier 'sources'
}

这里我们新建了类型为 Jar 的 Task,from 指定的是源代码的位置,classifier 会使生成的 jar 包带上 -sources 的后缀。

将 jar 包上传到 Maven 仓库

maven-publish 是 gradle 推出的用来替代 Upload Task 的 Plugin,具体用法可看 User Guide。我们使用 arfifact 方法来增加上传的文件。在 publishing 中添加一行,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
publishing {
publications {
aar(MavenPublication) {
groupId packageName
version libraryVersion
artifactId project.getName()
// Tell maven to prepare the generated "*.aar" file for publishing
artifact("$buildDir/outputs/aar/${project.getName()}-release.aar")
// 将 generateSourcesJar Task 生成的 sources.jar 也一并上传
artifact generateSourcesJar
}
}
}

为了方便起见,我们添加如下代码,使得执行 artifactoryPublish 之前会自动执行 assembleRelease、generateSourcesJar Task。

1
artifactoryPublish.dependsOn assembleRelease, generateSourcesJar

此时,我们运行 ./gradlew artifactoryPublish,就会把 aar 连同 sources.jar 上传到 Maven 仓库了。
上传 javadoc 的做法也是类似的,就不赘述了。

参考