搜索下如何發(fā)布 Android 項(xiàng)目的信息益眉,大部分都會(huì)找到這篇文章 Publishing Gradle Android Library to jCenter Repository,中文的指引可以看使用Gradle發(fā)布項(xiàng)目到JCenter倉庫。不過,如果按照這些文章提供的 build.gradle
毕匀,可能還會(huì)遇到一些坑熊杨。
調(diào)用 getBootClassPath() 出錯(cuò)
具體的錯(cuò)誤信息是
Cannot call getBootClasspath() before setTargetInfo() is called.
這個(gè)是 gradle 的 android plugin 1.1.0 版本的 bug肿轨,見 Issue 152811 - android - Android Gradle Plugin 1.1.0 breaks Javadoc tasks荡碾。將插件更新到 1.1.1 以上版本就可以了。
classpath 'com.android.tools.build:gradle:1.1.2'
GBK 編碼問題
Windows 用戶可能會(huì)遇到這個(gè)問題均践,因?yàn)槟銓⑽募O(shè)置為 UTF-8 編碼晤锹,javadoc 默認(rèn)的是系統(tǒng)編碼,Windows 就是 GBK 編碼彤委。所以一旦 java 文件中出現(xiàn)中文注釋就會(huì)報(bào)錯(cuò)鞭铆,提示無法映射的GBK編碼
。
這個(gè)很容易解決,為 javadoc 指明編碼就可以车遂。在 gradle 可以這么做: options.encoding = "utf-8"
封断,具體的任務(wù)代碼如下:
task javadoc(type: Javadoc) {
...
options.encoding = "utf-8"
...
}
javadoc 的依賴問題
task javadoc(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}
文章中的 javadoc
任務(wù)是這樣的,重點(diǎn)在 classpath 那一行舶担,這一行的意思是添加 Android 框架到 javadoc
的 classpath 中坡疼。不過,如果你的項(xiàng)目使用了其他第三方依賴衣陶,那 javadoc
任務(wù)很可能會(huì)執(zhí)行失敗的柄瑰,因?yàn)樯厦娴拇a并沒有這些添加第三方依賴到 classpath 中。比如我的項(xiàng)目剪况,有下面這些依賴:
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
就會(huì)報(bào)錯(cuò)教沾,類似下面的錯(cuò)誤:
xxxx.java:20: 錯(cuò)誤: 找不到符號(hào)
public static <T> T create(JsonElement json, Class<T> classOfModel) {
^
符號(hào): 類 JsonElement
位置: 類 xxxx
這時(shí)最簡單的方法就是把第三方依賴加入 classpath:
classpath += project.files(configurations.compile.files,android.getBootClasspath().join(File.pathSeparator))
但是仍然報(bào)錯(cuò)
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
...
這時(shí)我的 repositories 是這樣的:
allprojects {
repositories {
mavenLocal()
jcenter()
}
}
找不到 support 庫,因?yàn)?support 庫是 sdk 下載下來的译断,所以在這兩個(gè)位置找不到也很正常授翻。Android Plugin 自帶的任務(wù)執(zhí)行起來卻不會(huì)報(bào)錯(cuò),想必是做了特殊處理孙咪。
sdk 目錄下也有個(gè) maven repository堪唐,就是那些 support libs 所在的位置。
ANDROID_HOME\extras\android\m2repository
加進(jìn)去再試一下
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream()) // local.properties 有 sdk 的絕對(duì)位置
allprojects {
repositories {
maven {
url properties.getProperty("sdk.dir")+"/extras/android/m2repository"
}
mavenLocal()
jcenter()
}
}
依然報(bào)錯(cuò)该贾,這次是找到那些庫了羔杨,但因?yàn)?sdk 目錄下的庫是 aar 格式的,javadoc 不支持杨蛋。所以問題到這里近乎無解了,幸好我在 stackoverflow 找到另一個(gè) android 生成 javadoc 的方法理澎。稍加改寫就可以生成 javadoc 為 maven 所用:
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 確實(shí)有特殊處理糠爬。生成 javadoc 沒問題其他的也基本沒有什么問題寇荧,最終的 build.gradle
見 gist。
關(guān)于 javadoc 的坑寫得十分啰嗦执隧,主要是想和大家分享一些 gradle 的使用經(jīng)驗(yàn)揩抡,其實(shí) gradle 并不困難,主要是 Android Plugin 缺乏文檔又鮮有例子镀琉,所以折騰起來比較難受峦嗤。Android Plugin 的用戶指南是在 New Build System 而 DSL 文檔則是在 Android Plug-in for Gradle 右邊有個(gè)下載 DSL 文檔按鈕。Gradle 可看官方的用戶指南 Gradle User Guide屋摔,我還有一個(gè)亂糟糟的筆記這個(gè)不足為看了烁设。
如何上傳到 JCenter 這個(gè)按照一開始提及文章的操作應(yīng)該是沒什么問題的,反正我沒遇到問題钓试,成功上傳了 lru-image装黑。其實(shí)副瀑,不用上傳到 jcenter 單單運(yùn)行 install
任務(wù), gradle 會(huì)在 maven 的本地倉庫中生成工件(artifact)恋谭,只需將 mavenLocal 添加到 repositories糠睡,我們可以像發(fā)布到 JCenter 一樣引用自己的庫,方便打包那些多個(gè)項(xiàng)目共享又不想發(fā)布的私有庫疚颊。
allprojects {
repositories {
mavenLocal()
jcenter()
}
}