欢迎关注微信公众号:FSA全栈行动 👋html
"jCenter 不久后将中止服务" 这个消息对全部 Android 开发者的影响是很大的,不少好用的第三方库都会上传到 jCenter,并且几乎全部的 Android 项目里都会依赖到 jCenter 仓库,这意味着 Android 开发者对其有很强的依赖性。做为第三方库使用者来讲,一旦到了 jCenter 停服那时,只有 2 种选择:java
如下是其余人对 jCenter 停服事件的见解文章推荐,有兴趣能够去看看:
《浅谈 JCenter 即将被中止服务的事件》android
回归主题,若是你是一个第三方库开发者,且以前没有上传库到 MavenCentral 经验的话,本文能够助你早日上传库到 MavenCentral~git
MavenCentral 和 Sonatype 的关系至关于 jCenter 和 jForg:github
库平台 | 运营商 | 管理后台 |
---|---|---|
jCenter | jForg | bintray.com |
MavenCentral | Sonatype | oss.sonatype.org |
注意:最新管理后台连接是:
s01.oss.sonatype.org
,详情见central.sonatype.org/publish/rel…apache
因此,在上传库到 MavenCentral 以前,须要先注册登陆 Sonatype,访问 issues.sonatype.org :api
若是你已经有帐号,则直接登陆,不然点击 Sign up
进入注册页面:缓存
填写好帐号、密码、邮箱等信息便可注册成功,注册成功后再登陆 Sonatype。服务器
注意:邮箱很重要,建议是你经常使用的邮箱,才能及时收到 Sonatype 在 issue 中给你的答复信息提醒。微信
如今你已经有 Sonatype 帐号了,接下来理应就是借助 grdle 脚本经 管理后台(s01.oss.sonatype.org
) 把库上传到 MavenCentral ,可是,Sonatype 新用户默认是没有这个权限的,不信你能够访问 s01.oss.sonatype.org后,点击右上角 "Log In" 登陆试试看,会提示没有权限:
注意:出现这个弹窗有 2 种可能,一种是帐号密码错误,另外一种没有权限。
因此,如今咱们须要让 Sonatype 给咱们开通这个权限,回到登陆成功后跳转的那个页面issues.sonatype.org,点击顶部的 新建
按钮,填写项目信息:
注意:图中是我我的项目信息,只是举例,不要照抄!!
这个步骤中,惟一须要注意的地方就是 Group Id
,有两种状况:
io.github.username
,好比个人 github 帐号名是 GitLqr,那么能够填写 io.github.gitlqr
。com.gitlqr
,另外,还须要在 DNS 配置中配置一个 TXT 记录来验证域名全部权,具体请看:central.sonatype.org/pages/produ…注意:目前已经不能再使用
com.github
域名了,具体缘由请看:central.sonatype.org/changelog/#…;使用本身的网站域名时,建议写顶级域名,不须要具体到某个项目的子域名,如此一来,Group Id
只须要申请一次,之后你的其余库都使用同一个Group Id
便可。
填写信息后,点击"新建"按钮,开启一个 issue,会显示 wait for response
,等待 Sonatype 工做人员审核回复:
由于 Sonatype 是国外运营,因此工做时间上会有时差,咱们须要耐心等待 Sonatype 工做人员处理这个 issue,好比我这样:
注意:若是你想尽快上传库,那么前面已经提到了,请使用你经常使用的邮箱,当 Sonatype 工做人员评论时,会第一时间经过邮件通知到你。
首次向 Sonatype 申请上传权限可能会有点久,咱们能够同步处理 gradle 配置。
在项目根目录下新建一个 maven-publish.gradle
文件,内容以下:
注意:如下内容是通用配置,直接拷贝便可。
if (project.hasProperty("android")) { // Android libraries
task sourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.srcDirs
}
task javadoc(type: Javadoc) {
// https://github.com/novoda/bintray-release/issues/71
excludes = ['**/*.kt'] // < ---- Exclude all kotlin files from javadoc file.
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
options.encoding = "utf-8"
options.charSet = "utf-8"
}
} else { // Java libraries
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
}
// 强制 Java/JavaDoc 等的编码为 UTF-8
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
tasks.withType(Javadoc) {
options.encoding = "UTF-8"
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
// add javadoc/source jar tasks as artifacts
artifacts {
archives javadocJar
archives sourcesJar
}
apply plugin: 'maven'
apply plugin: 'signing'
//Properties properties = new Properties()
//properties.load(project.rootProject.file('local.properties').newDataInputStream())
//
//def ossrhUsername = properties.getProperty("ossrhUsername")
//def ossrhPassword = properties.getProperty("ossrhPassword")
def PUBLISH_GROUP_ID = publishedGroupId //这里能够不是直接申请时候的groupId只要开头是就能够
def PUBLISH_ARTIFACT_ID = artifact
def PUBLISH_VERSION = libraryVersion // android.defaultConfig.versionName //这个是直接获取的库gradle里配置好的版本号,不用处处修改版本号,只须要维护一份就能够。
//签名
signing {
required { gradle.taskGraph.hasTask("uploadArchives") }
sign configurations.archives
}
uploadArchives {
repositories {
mavenDeployer {
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
repository(url: "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") {
authentication(userName: ossrhUsername, password: ossrhPassword)
}
snapshotRepository(url: "https://s01.oss.sonatype.org/content/repositories/snapshots/") {
authentication(userName: ossrhUsername, password: ossrhPassword)
}
pom.groupId = PUBLISH_GROUP_ID
pom.artifactId = PUBLISH_ARTIFACT_ID
pom.version = PUBLISH_VERSION
pom.project {
packaging 'aar' //我这里发布的是安卓的包,全部写的aar
name libraryName // '发布库的简单名称'
// optionally artifactId can be defined here
description libraryDescription // '发布包的描述'
url siteUrl // '能够写公司官网地址或github我的页面地址'
scm {
connection gitUrl // 'scm:替换成项目git地址'
developerConnection gitUrl // 'scm:替换为git开头的项目地址'
url siteUrl // '项目首页,能够是github项目的主页'
}
licenses {
license {
name licenseName // 'The Apache License, Version 2.0'
url licenseUrl // 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
developers {
developer {
id developerId // '这里填写申请帐号时候的全名就能够'
name developerName // '这里随意填写就能够'
email developerEmail// '最好是申请帐号时用的邮箱'
}
}
}
}
}
}
复制代码
库信息共用两处配置:
gradle.prperties
文件中。build.gradle
文件中。gradle.prperties
配置publishedGroupId=你申请权限时填写的GroupId
siteUrl=项目url
gitUrl=git连接
developerId=帐号id
developerName=帐号id
developerEmail=邮箱
licenseName=The Apache Software License, Version 2.0
licenseUrl=http://www.apache.org/licenses/LICENSE-2.0.txt
allLicenses=["Apache-2.0"]
复制代码
具体可参考 github.com/GitLqr/Lite…
build.gradle
配置ext {
artifact = '库的惟一标识'
libraryName = '发布库的简单名称'
libraryDescription = '发布包的描述'
libraryVersion = '发布库的版本号'
}
复制代码
具体可参考 github.com/GitLqr/Lite…
在库对应的 Module 目录下的build.gradle
文件底部添加以下代码:
apply from: '../maven-publish.gradle'
复制代码
在 AS 中 Sync Now
一下 Gradle,就能够在 Gradle 面板中看到多了一个 upload/uploadArchives
任务了。
经过以上两步以后,还差最后一步,此时你运行 uploadArchives
任务是没法正常提交的,MavenCentral 提交还须要配置 GPG 签名文件。
注意:如下生成 GPG 密钥的操做流程使用的是 Window 环境,若是你使用的是 Mac,请参考:www.jianshu.com/p/1c715203c…
先到www.gpg4win.org/get-gpg4win…下载安装好 Gpg4win:
启动 Gpg4win,点击 "文件" - "新建密钥对...":
建立我的 OpenPGP 密钥对:
填写帐号、邮箱,并勾选 Protect the generated key with a passphrase
:
注意:在高级设置里能够设置更详细的,例如过时时间,但过时时间不能够太长,或报错。
点击 "新建", 设置密码(确认密码):
等待生成密钥后,出现以下弹窗,点击 "完成":
在主界面双击刚刚建立好的密钥,会出现以下弹窗,须要把底部的那 8 个字符复制下来,在后面的【配置密钥】环节会用到:
在主界面右击刚刚建立好的密钥,点击 "在服务器上发布...",而后一路肯定:
在主界面右击刚刚建立好的密钥,点击 "导出...",这时注意了,必定要在这里先把文件名改为 "gpg" 或者 "pgp",再点保存:
注意了,Gpg4win 的导出分为两种:
"导出..."
: 导出公钥"Backup Secret Keys"
: 导出 私钥
!!提示:后续步骤须要用到的是
私钥
,因此须要点"Backup Secret Keys"
导出私钥的 gpg 文件;导出时默认文件后缀是 "asc",必定要在这时修改后缀为 "gpg",这样才能生成正确的二进制 gpg 密钥文件
。若是先保存成asc 文本文件
,再修改为 gpg 是没有用的!!!
这一步很关键,须要在电脑 用户目录
下的 .gradle/gradle.properties
中配置以下内容:
好比:
C:\Users\CharyLin\.gradle\gradle.properties
# MavenCentral
signing.keyId=刚才获取的密钥后8位
signing.password=以前咱们执行命令时设置的密码
signing.secretKeyRingFile=刚才生成的gpg文件路径
ossrhUsername=sonatype用户名
ossrhPassword=sonatype密码
复制代码
到了这一步,就能够去 Gradle 面板中双击执行 uploadArchives
任务了,成功的话,会出现以下日志:
11:12:00: Executing task 'uploadArchives'...
...
> Task :litearouter-api:sourcesJar UP-TO-DATE
> Task :litearouter-api:signArchives UP-TO-DATE
> Task :litearouter-api:uploadArchives
...
BUILD SUCCESSFUL in 16s
23 actionable tasks: 1 executed, 22 up-to-date
11:12:16: Task execution finished 'uploadArchives'.
复制代码
若是出现 Unable to read secret key from file: it may not be a PGP secret key ring
的错误,有如下三种可能:
FAILURE: Build failed with an exception.
* What went wrong:
Could not evaluate onlyIf predicate for task ':litearouter-annotation:signArchives'.
> Unable to read secret key from file: D:\CharyLinDatas\GitLqr\secret.gpg (it may not be a PGP secret key ring)
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 11s
复制代码
如今能够去登陆下的管理后台 s01.oss.sonatype.org/, 而后点击左侧的 "Staging Repositories":
选中刚上传的包, 底部的 Content
选项卡下,能够看到包内的文件有哪些:
肯定无误后, 点击 "Close", 填写描述信息, 而后点击 "Confirm":
正常状况下, 等待几分钟后, Activity
选项卡中出现对号的 "Repository closed" 就是 close 成功了:
而后再点击 "Release" 按钮便可发布到 MavenCentral, 等待几个小时后能够在 search.maven.org/ 查询发布结果。
由于 Release 时勾选了 "Automatically Drop" 选项, 因此当包发布成功以后会自动从 Staging Repository 中删除。
须要注意的是, 若是你的库有好几个 component, 像个人项目就包含了 litearouter-annotation
、litearouter-api
、litearouter-compiler
三个, 切记一个一个按流程来, 好比:
litearouter-annotation
: upload --> close --> releaselitearouter-api
: upload --> close --> releaselitearouter-compiler
: upload --> close --> release不要一次性所有 upload, 而后又一次性 close, 最后再一次性 release, 这种作法不肯定会带来什么后果, 建议不要这样搞。
Group Id
是什么gradle 中会使用 implementation
来依赖某个第三方库,结构为:implementation GroupId:ArtifactId:Version
:
好比:
implementation 'com.android.support:appcompat-v7:27.1.1'
组成部分 | 解释 |
---|---|
GroupId | 是项目组织的惟一标识符,在实际开发中通常对应 JAVA 的包的结构,就是 main 目录里 java 的目录结构,如 ‘com.android.support’。 |
ArtifactId | 是项目的惟一标识符,在实际开发中通常对应项目的名称,就是项目根目录的名称,例:appcompat-v7。 |
Version | 是项目的版本号,例:1.0-SNAPSHOT 。其中 1.0 是版本号,SNAPSHOT 版本表明不稳定、尚处于开发中的版本。而衍生的有 Release 版本则表明稳定的版本 |
注意:这里说的是 GroupId
通常
对应包结构,也就是说,GroupId
与包名
是能够不同的。就像 Android 项目里的applicationId
跟包名
是两个不一样的概念同样。
若是文章对您有所帮助, 请不吝点击关注一下个人微信公众号:FSA全栈行动, 这将是对我最大的激励. 公众号不只有Android技术, 还有iOS, Python等文章, 可能有你想要了解的技能知识点哦~