Android 项目打包到 JCenter 的坑

转载自: http://www.jianshu.com/p/c721f9297b2f?utm_campaign=hugo&utm_medium=reader_share&utm_content=note 

搜索下如何发布 Android 项目的信息,大部分都会找到这篇文章 Publishing Gradle Android Library to jCenter Repository,中文的指引可以看使用Gradle发布项目到JCenter仓库。不过,如果按照这些文章提供的 build.gradle,可能还会遇到一些坑。

调用 getBootClassPath() 出错

具体的错误信息是

1
Cannot call getBootClasspath() before setTargetInfo() is called.

这个是 gradle 的 android plugin 1.1.0 版本的 bug,见 Issue 152811 - android - Android Gradle Plugin 1.1.0 breaks Javadoc tasks。将插件更新到 1.1.1 以上版本就可以了。

1
classpath  'com.android.tools.build:gradle:1.1.2'

GBK 编码问题

Windows 用户可能会遇到这个问题,因为你将文件设置为 UTF-8 编码,javadoc 默认的是系统编码,Windows 就是 GBK 编码。所以一旦 java 文件中出现中文注释就会报错,提示无法映射的GBK编码

这个很容易解决,为 javadoc 指明编码就可以。在 gradle 可以这么做: options.encoding = "utf-8",具体的任务代码如下:

1
2
3
4
5
task javadoc(type: Javadoc) {
     ...
     options.encoding =  "utf-8"
     ...
}

javadoc 的依赖问题

1
2
3
4
task javadoc(type: Javadoc) {
     source = android.sourceSets.main.java.srcDirs
     classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}

文章中的 javadoc 任务是这样的,重点在 classpath 那一行,这一行的意思是添加 Android 框架到 javadoc 的 classpath 中。不过,如果你的项目使用了其他第三方依赖,那 javadoc 任务很可能会执行失败的,因为上面的代码并没有这些添加第三方依赖到 classpath 中。比如我的项目,有下面这些依赖:

1
2
3
4
5
6
7
dependencies {
     compile fileTree(dir:  'libs' , include: [ '*.jar' ])
     compile  'com.google.code.gson:gson:2.3.1'
     compile  'com.android.support:gridlayout-v7:22.1.1'
     compile  'com.android.support:support-v4:22.1.1'
     compile  'com.android.support:appcompat-v7:22.1.1'
}

跑起上面的 javadoc 就会报错,类似下面的错误:

1
2
3
4
5
     xxxx.java:20: 错误: 找不到符号
     public static <T> T create(JsonElement json, Class<T> classOfModel) {
                                ^
   符号:   类 JsonElement
   位置: 类 xxxx

这时最简单的方法就是把第三方依赖加入 classpath:

1
  classpath += project.files(configurations.compile.files,android.getBootClasspath().join(File.pathSeparator))

但是仍然报错

1
2
3
4
5
6
7
Error:Could not find com.android.support:gridlayout-v7:22.1.1.
Searched  in  the following locations:
USER_HOME/.m2/repository/com/android/support/gridlayout-v7/22.1.1/gridlayout-v7-22.1.1.pom
USER_HOME/.m2/repository/com/android/support/gridlayout-v7/22.1.1/gridlayout-v7-22.1.1.jar
https: //jcenter.bintray.com/com/android/support/gridlayout-v7/22.1.1/gridlayout-v7-22.1.1.pom
https: //jcenter.bintray.com/com/android/support/gridlayout-v7/22.1.1/gridlayout-v7-22.1.1.jar
...

这时我的 repositories 是这样的:

1
2
3
4
5
6
allprojects {
     repositories {
         mavenLocal()
         jcenter()
     }
}

找不到 support 库,因为 support 库是 sdk 下载下来的,所以在这两个位置找不到也很正常。Android Plugin 自带的任务执行起来却不会报错,想必是做了特殊处理。

sdk 目录下也有个 maven repository,就是那些 support libs 所在的位置。

ANDROID_HOME\extras\android\m2repository

加进去再试一下

1
2
3
4
5
6
7
8
9
10
11
Properties properties =  new  Properties()
properties.load(project.rootProject.file( 'local.properties' ).newDataInputStream())  // local.properties 有 sdk 的绝对位置
allprojects {
     repositories {
         maven {
             url properties.getProperty( "sdk.dir" )+ "/extras/android/m2repository"
         }
         mavenLocal()
         jcenter()
     }
}

依然报错,这次是找到那些库了,但因为 sdk 目录下的库是 aar 格式的,javadoc 不支持。所以问题到这里近乎无解了,幸好我在 stackoverflow 找到另一个 android 生成 javadoc 的方法。稍加改写就可以生成 javadoc 为 maven 所用:

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
android.libraryVariants.all { variant ->
     println variant.javaCompile.classpath.files
     if (variant.name ==  'release' ) {  //我们只需 release 的 javadoc
         task( "generate${variant.name.capitalize()}Javadoc" , type: Javadoc) {
             // title = ''
             // description = ''
             source = variant.javaCompile.source
             classpath = files(variant.javaCompile.classpath.files, project.android.getBootClasspath())
             options {
                 encoding  "utf-8"
                 links  "http://docs.oracle.com/javase/7/docs/api/"
                 linksOffline  "http://d.android.com/reference" "${android.sdkDirectory}/docs/reference"
             }
             exclude  '**/BuildConfig.java'
             exclude  '**/R.java'
         }
         task( "javadoc${variant.name.capitalize()}Jar" , type: Jar, dependsOn:  "generate${variant.name.capitalize()}Javadoc" ) {
             classifier =  'javadoc'
             from tasks.getByName( "generate${variant.name.capitalize()}Javadoc" ).destinationDir
         }
         artifacts {
             archives tasks.getByName( "javadoc${variant.name.capitalize()}Jar" )
         }
     }
}

以 support-v4 为例,configurations.compile 和 variant.javaCompile.classpath 打印出来的位置是不同的,分别是

  • SDK_HOME\extras\android\m2repository\com\android\support\support-v4\22.1.1\support-v4-22.1.1.aar

  • PROJECT_HOME/MODULE/build/intermediates/exploded-aar/com.android.support/support-v4/22.1.1/jars/libs/internal_impl-22.1.1.jar

看来 Android Plugin 确实有特殊处理。生成 javadoc 没问题其他的也基本没有什么问题,最终的 build.gradle 见 gist

关于 javadoc 的坑写得十分啰嗦,主要是想和大家分享一些 gradle 的使用经验,其实 gradle 并不困难,主要是 Android Plugin 缺乏文档又鲜有例子,所以折腾起来比较难受。Android Plugin 的用户指南是在 New Build System 而 DSL 文档则是在 Android Plug-in for Gradle 右边有个下载 DSL 文档按钮。Gradle 可看官方的用户指南 Gradle User Guide,我还有一个乱糟糟的笔记这个不足为看了。

如何上传到 JCenter 这个按照一开始提及文章的操作应该是没什么问题的,反正我没遇到问题,成功上传了 lru-image。其实,不用上传到 jcenter 单单运行 install 任务, gradle 会在 maven 的本地仓库中生成工件(artifact),只需将 mavenLocal 添加到 repositories,我们可以像发布到 JCenter 一样引用自己的库,方便打包那些多个项目共享又不想发布的私有库。

1
2
3
4
5
6
allprojects {
     repositories {
         mavenLocal()
         jcenter()
     }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值