(点击
上方公众号
,可快速关注)
来源:
Etienne Lawlor
译文:伯乐在线 - 沉默水狮
http://android.jobbole.com/83269/
如有好文章投稿,请点击 → 这里了解详情
我经常被 android 开发社区中如此多而且好用的第三方库所震惊。有很长的一段时间,我想贡献一些东西,但我不知道如何去做。在浏览了其他很多关于如何发布一个 android 开发库的文章后,我仍然发现缺失了一些细节,而且,所有的信息都是在不同的地方。所以,我将完整的走过这个过程,向大家展示我的做法。
对新手来说,我推荐使用 Android Studio 来创建所有的 Android 项目,Android Studio官方使用 Gradle 构建系统。请确保你下载了
Android Studio
的最新版。
相关术语介绍
在我们开始之前,还有一些术语,需要熟悉下。
项目(Project)
— 在 Android Studio 中,一个 项目 就是一个完整的 Android app。Android Studio 项目包含了一个或多个模块。 在 Android Studio 中,一个 项目 类似于在 Eclipse 的一个工作区间( workspace )。
模块( Module)
– 一个 模块 是 app 中的一个组件,它可以单独的进行构建、测试和调试。模块包含了 app 的源代码和资源文件。在 Android Studio 中,一个 模块 类似于在 Eclipse 的一个项目。
AAR – ‘aar’ 套件
是 Android 开发库项目的二进制的分发形式。(AAR 格式)开发库项目的主要产出就是 .aar 包(意思是 Android 压缩包)。它是由编译后的代码(如 jar 文件或者 .so 文件)和资源文件(如 manifest 文件、res 文件、asset 文件)组合而成的。
Maven 中央仓库
– 由 Maven 社区提供的仓库。它包含了很多我们常用的开发库。 Search Maven 网站可用来浏览 maven 中央仓库的内容。Gradle, Please 网站是另一个可用来搜索中央仓库的工具。如果你在项目配置文件的仓库配置部分添加了 jCenter() ,那么 Gradle 将使用 jCenter 仓库( jCenter 的说明)。Maven 中央仓库也经常被称作 Maven 中心或者中央仓库。
Sonatype
— Sonatype的开源软件仓库托管(OSSRH)服务是项目作者和贡献者们发布他们的组件到中央仓库的主要途径。它是 Sonatype Nexus Professional 组织利用 Nexus Staging Suite 工具,对开源项目提供部署托管服务,该服务主要用来处理部署和验证操作,也提供同步操作将内容通过网络投递到中央仓库。
GPG
– GNU 隐私保护组织 (也称为 GPG 或者 GnuPG),这个 GNU 项目是一个加密软件,遵循 OpenPGP (RFC4880)标准,是 PGP 的免费替代品。使用 GPG 你可以加密(解密)包含敏感数据的文件,比如那些由健康保险携带和责任法案 (HIPAA) 制定的受保护的隐私和安全方面的电子健康信息。想了解 GPG 的更多信息,请访问 GNU Privacy Guard website。
准备好你的 Android 开发库
我将使用我的 Trestle 开发库作例子来讲解。在你的项目中,需要修改一些地方,来准备作为一个开发库发布到 Maven 中央仓库中。
apply
plugin
:
'com.android.application'
dependencies
{
compile project
(
':library'
)
}
apply
plugin
:
'com.android.library'
apply
from
:
'maven-push.gradle'
POM_NAME
=
ProjectName
POM_ARTIFACT_ID
=
projectname
POM_PACKAGING
=
aar
/*
* Copyright 2013 Chris Banes
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
apply
plugin
:
'maven'
apply
plugin
:
'signing'
def isReleaseBuild
()
{
return
VERSION_NAME
.
contains
(
"SNAPSHOT"
)
==
false
}
def getReleaseRepositoryUrl
()
{
return
hasProperty
(
'RELEASE_REPOSITORY_URL'
)
?
RELEASE_REPOSITORY_URL
:
"https://oss.sonatype.org/service/local/staging/deploy/maven2/"
}
def getSnapshotRepositoryUrl
()
{
return
hasProperty
(
'SNAPSHOT_REPOSITORY_URL'
)
?
SNAPSHOT_REPOSITORY_URL
:
"https://oss.sonatype.org/content/repositories/snapshots/"
}
def getRepositoryUsername
()
{
return
hasProperty
(
'NEXUS_USERNAME'
)
?
NEXUS_USERNAME
:
""
}
def getRepositoryPassword
()
{
return
hasProperty
(
'NEXUS_PASSWORD'
)
?
NEXUS_PASSWORD
:
""
}
afterEvaluate
{
project
-&
amp
;
gt
;
uploadArchives
{
repositories
{
mavenDeployer
{
beforeDeployment
{
MavenDeployment
deployment
-&
amp
;
gt
;
signing
.
signPom
(
deployment
)
}
pom
.
groupId
=
GROUP
pom
.
artifactId
=
POM_ARTIFACT_ID
pom
.
version
=
VERSION_NAME
repository
(
url
:
getReleaseRepositoryUrl
())
{
authentication
(
userName
:
getRepositoryUsername
(),
password
:
getRepositoryPassword
())
}
snapshotRepository
(
url
:
getSnapshotRepositoryUrl
())
{
authentication
(
userName
:
getRepositoryUsername
(),
password
:
getRepositoryPassword
())
}
pom
.
project
{
name
POM_NAME
packaging
POM_PACKAGING
description
POM_DESCRIPTION
url
POM_URL
scm
{
url POM_SCM_URL
connection POM_SCM_CONNECTION
developerConnection
POM_SCM_DEV
_
CONNECTION
}
licenses
{
license
{
name POM_LICENCE_NAME
url POM_LICENCE_URL
distribution
POM_LICENCE
_
DIST
}
}
developers
{
developer
{
id POM_DEVELOPER_ID
name
POM_DEVELOPER
_
NAME
}
}
}
}
}
}
signing
{
required
{
isReleaseBuild
()
&
amp
;
amp
;
&
amp
;
amp
;
gradle
.
taskGraph
.
hasTask
(
"uploadArchives"
)
}
sign
configurations
.
archives
}
//task androidJavadocs(type: Javadoc) {
//source = android.sourceSets.main.allJava
//}
//task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
//classifier = 'javadoc'
//from androidJavadocs.destinationDir
//}
task androidSourcesJar
(
type
:
Jar
)
{
classifier
=
'sources'
from
android
.
sourceSets
.
main
.
java
.
sourceFiles
}
artifacts
{
archives
androidSourcesJar
}
}
#
[
Android
]
========================
#
Built application
files
*
.
apk
*
.
ap_
#
Files
for
the Dalvik
VM
*
.
dex
#
Java
class
files
*
.
class
#
Generated files
bin
/
gen
/
#
Gradle
files
.
gradle
/
build
/
#
Local configuration file
(
sdk
path
,
etc
)
local
.
properties
#
Proguard folder generated by Eclipse
proguard
/
#
Log
Files
*
.
log
##
Directory
-
based project
format
:
.
idea
/
##
File
-
based project
format
:
*
.
ipr
*
.
iws
##
Plugin
-
specific
files
:
#
IntelliJ
out
/
#
mpeltonen
/
sbt
-
idea
plugin
.
idea_modules
/
#
JIRA plugin
atlassian
-
ide
-
plugin
.
xml
#
Crashlytics plugin
(
for
Android Studio
and
IntelliJ
)
com_crashlytics_export_strings
.
xml
#
[
Maven
]
========================
target
/
pom
.
xml
.
tag
pom
.
xml
.
releaseBackup
pom
.
xml
.
versionsBackup
pom
.
xml
.
next
release
.
properties
#
[
Gradle
-
Android
]
========================
#
Ignore Gradle GUI config
gradle
-
app
.
setting
#
Gradle Signing
signing
.
properties
trestle
.
keystore
#
Mobile Tools
for
Java
(
J2ME
)
.
mtj
.
tmp
/
#
Package
Files
#
*
.
jar
*
.
war
*
.
ear
#
virtual machine crash
logs
,
see
http
:
//www.java.com/en/download/help/error_hotspot.xml
hs_err_pid
*
#
Misc
/
.
idea
/
workspace
.
xml
.
DS_Store
/
captures
**/*
.
iml
*
.
class
include ':sample', ':library'
#
Project
-
wide Gradle
settings
.
#
IDE
(
e
.
g
.
Android
Studio
)
users
:
#
Gradle settings configured through the
IDE
*
will
override
*
#
any settings specified
in
this
file
.
#
For
more details on how
to
configure your build environment
visit
#
http
:
//www.gradle.org/docs/current/userguide/build_environment.html
#
Specifies the JVM arguments used
for
the daemon
process
.
#
The setting
is
particularly useful
for
tweaking memory
settings
.
#
Default
value
: -
Xmx10248m
-
XX
:
MaxPermSize
=
256m
#
org
.
gradle
.
jvmargs
=-
Xmx2048m
-
XX
:
MaxPermSize
=
512m
-
XX
:+
HeapDumpOnOutOfMemoryError
-
Dfile
.
encoding
=
UTF
-
8
#
When
configured
,
Gradle will run
in