网站建设移交内容,交通网站建设,深圳网站制作公司嘉兴,怎么建公众号申请最近领导给安排了个任务#xff0c;让我把我们现有的一个 SDK 上传到 Maven 上去#xff0c;方便客户直接用 gradle 依赖#xff0c;不再需要拷贝 jar 和 so 了#xff0c;此前我也看过一些相关的文章我想问题也不大#xff0c;觉得工作量也就一两天的事情#xff0c;主要…最近领导给安排了个任务让我把我们现有的一个 SDK 上传到 Maven 上去方便客户直接用 gradle 依赖不再需要拷贝 jar 和 so 了此前我也看过一些相关的文章我想问题也不大觉得工作量也就一两天的事情主要的难点在于如何隐藏源码上传 maven因为是商业 SDK万万没想到问题这么多网上有用的文章也很少加上 gradle 的版本捣捣乱让我整整一周焦头烂额一言难尽略过直接进入正题
前期准备
AndroidStudio 版本不同版本默认的 gradle 版本不同 Gradle 版本
classpath com.android.tools.build:gradle:4.1.3
distributionUrlhttps\://services.gradle.org/distributions/gradle-6.5-bin.zip总体流程
注册 sonatype 账号并申请 groupid压缩 jar、so、其它资源到 aar编写 gradle 脚本解决源码混淆问题非商用 SDK 可跳过解决文档 javadoc 问题非商用 SDK 可跳过GPG 签名上传
注册 sonatype 并申请 group id
buildscript {repositories {jcenter()google()mavenCentral()}dependencies {...}
}我们在项目的 gradle.build 中一般都有这么一段代码其中 repositories 下的每一行代码代表一种远程代码仓库其中 jcenter 已于 2021 年 3 月 31 日被设定为只读代码库从 AndroidStudio 中也可以看到相关的提醒 google 代表的是 google 提供的代码仓库mavenCentral 则代表着我们想要上传的仓库但这个 mavenCentral 它不能直接上传它需要通过它所支持的第三方仓库来同步更新。也就是说你想要上传一个包需要上传到它指定的一个第三方代码仓库中第三方仓库会定时与 mavenCentral 同步在同步后你就可以在 mavenCentral 中找到它了其中 sonatype 是一个比较好的代码仓库上传和同步都比较及时。
注册 sonatype 第一步不要去 google 搜索 sonatype那会让你不知所措。搜到的大概率是这个东西 Sontype 管理代码库的申请用的是 jira所以你要注册它的账号需要登录这个网站
https://issues.sonatype.org/secure/Signup!default.jspa 这里的密码有点烦它不会一下子告诉你该有什么要求每次都是填完密码、验证码后点 sign up 然后告诉你本次的密码哪里不合格错了好多遍之后我知道了所有的密码要求
必须大于等于 8 位必须有英文和数字和特殊符号三种缺一不可必须同时包含大写和小写
登录之后你想申请一个 group id 需要创建一个 issuelabel 选 Community Support - Open Source Project Repository Hosting (OSSRH)问题类型选 new project。 Group id 这里要认真填写它对应的是下图中红框圈出的部分如果你拥有一个域名可以填写 com.你的域名不要填写你无法影响的域名后面会让你在 DNS 解析上加记录来验证域名是你所有的。这里也可以填写你的 github 地址例如我的为 io.github.shaolongfei。 Project url 这里填写你的项目地址一般这里为 git 地址例如我的 https://github.com/ShaoLongFei/AndroidOpenGL。
scm url 这里写你项目的下载方式一般这里也可以填 git 地址例如我的 https://github.com/ShaoLongFei/AndroidOpenGL.git。
username 是你希望发布包时的用户名非必填项没必要写也不会审核这个后面想写可以直接配置在 gradle 脚本上。
alread synced to central是否已经同步到 mavenCentral 代码库保持为 no 就可以我觉得看这篇文章的人应该没有 yes 的吧。
提交之后这个 issue 会自动分配人员来对你提交的信息进行审核由于他们的审核人员在国外所以会有一些时差白天提交的话过一晚上就能收到回复了晚上 10 点提交的话过一会就能收到回复。下面是我的回复 我提交了一个 com.liuyue 的 group id 它让我在 DNS 上加一条记录但由于我并不拥有这个域名所以我选了下面的一个操作更改 group id 为 io.github.shaolongfei 在我的 github 上建一个他指定名称的库来验证 github 账号确实是我所有的。
在我做好这个操作后更改这个 issue 的状态为 open可以 comment 一下状态就会改变了 这样审核人员就会再次处理了。 收到这样的回复就代表你已经通过审核了。group id 的申请也就完成了。
压缩 jar、so、其它资源到 aar
以前客户使用我们的 sdk 都是分别拷贝 jar、so、资源文件到客户的项目中进行依赖这样的优势是灵活由于我们的 so 是分模块的如果客户不想用某些功能可以根据自己的需求进行裁剪也可以根据自己想要的 so 的架构进行依赖因为几种架构的 so 体积加起来还挺大的而上 maven 就不能散着了需要打成一个 aar 把 jar 、so 、资源文件都放进去这样的优势是客户使用起来很方便。
我们的项目是有两个 moudle 的每个 moudle 会打出来一个 jar 平时打 jar 包的流程是各自打 aar 包分别解压出来 jar将两个 jar 合并到一起。那打 aar 我原先的思路是在此前打 jar 的基础上往里面放入各个架构的 so 和指定路径的资源文件最后搞了搞发现完全不需要这么麻烦还得自己写脚本。
我找到了一个神器 https://github.com/kezong/fat-aar-android
这个用起来非常方便非常简单几行代码就可以解决打 aar 的各种烦恼什么依赖库冲突什么多 moudle 混淆规则合并AndroidManifest 合并R.class 合并等等问题它都能搞定。工欲善其事必先利其器啊。
Apply classpath
第一步在项目的 build.gradle 中加入 mavenCentral 和 classpath
buildscript {repositories {mavenCentral()}dependencies {classpath com.github.kezong:fat-aar:1.3.8}
}Add plugin
第二步在项目主 library 中的 build.gradle 添加此插件
apply plugin: com.kezong.fat-aarEmbed dependencies
第三步embed 你所需要的工程, 用法类似 implementation。
embed 的工程会被压缩到 aar 中implementation 的项目只参与编译的过程不会参与打包的过程。
dependencies {implementation com.qiniu:qiniu-android-sdk:8.3.2embed project(:MediaLibrary)
}执行 assemble 命令
此时配置已经完成了在 AndroidStudio 的右侧 Gradle 任务栏里可以找到 assemble 任务、assembleDebug 任务和 assembleRelease 任务。 执行 assemble 任务可以打出来 library-debug.aar 和 library-release.aar执行 assembleDebug 任务可以打出来 library-debug.aar执行 assembleRelease 任务可以打出来 library-release.aar。
打出来的 aar 都在 build/outputs/aar 路径下。 **注意**如果你在 AndroidStudio 右侧的 gradle 任务列表里找不到这些任务那你需要在 AndroidStudio 的设置中取消下图勾画的这一项设置这个设置是新版的 AndroidStudio 默认勾画的取消它 如果你习惯了命令行的话也可以直接在项目根目录下敲这些命令
# 产物library-debug.aar 和 library-release.aar
./gradlew assemble
# 产物library-debug.aar
./gradlew assembleDebug
# 产物library-release.aar
./gradlew assembleRelease编写 gradle 脚本
先上代码解释都在注释里
plugins {id signingid maven-publish
}task sourcesJar(type: Jar) {from android.sourceSets.main.java.srcDirsclassifier sources
}task javadoc(type: Javadoc) {source android.sourceSets.main.java.srcDirsclasspath project.files(android.getBootClasspath().join(File.pathSeparator))
}task javadocJar(type: Jar, dependsOn: javadoc) {classifier javadocfrom javadoc.destinationDir
}// 发布任务
publishing {publications {maven(MavenPublication) {artifact build/outputs/aar/library-release.aar // 产物artifact sourcesJarartifact javadocJargroupId io.github.shaolongfei // 此前在 sonatype 上申请的artifactId OpenGLESUtils // 项目的名称依赖的时候要用到的version 0.0.18 // 项目版本pom {name OpenGLESUtils /// 项目名称packaging aar // 发布的形式url https://github.com/ShaoLongFei/AndroidOpenGL // 项目地址description OpenGLES 常用的工具类 // 项目描述scm {connection scm:git:git://ShaoLongFei/AndroidOpenGL.gitdeveloperConnection scm:git:ssh://ShaoLongFei/AndroidOpenGL.giturl https://github.com/ShaoLongFei/AndroidOpenGL}//开源协议licenses {license {name The Apache License, Version 2.0url http://www.apache.org/licenses/LICENSE-2.0.txt}}// sdk 发布者信息developers {developer {name liuyue // 发布者名称email liuyueshaolongfeifoxmail.com // 联系邮箱}}}}}repositories {mavenLocal() // 发布到本地目录在 username/.m2/repository/ 下maven {name sonatypeRepositoryurl https://s01.oss.sonatype.org/content/repositories/releases/credentials {username // 之前在 sonatype 注册的账户名password // 对应的密码}}}
}// 不可打乱顺序
signing {sign configurations.archives
}这是我查了好多文章总结出来的写法网上很多文章讲的都是老版本的 maven 插件现在它已经被弃用了需要使用新版本的 maven-publish 插件才可以新老版本差异还是挺大的比如老版本的上传任务是 uploadArchives 新版本的是 publishing。
publishing 下面套 publications 再套 maven(MavenPublication)这个配置可以满足绝大多数需求非必要别改动。
artifact 声明的是要上传的东西可以声明多行每行一个它自己会把它们集合到一起也可以用大括号的形式声明一个列表
artifact{......
}sourcesJar 和 javadocJar 这两个 task 可以直接照搬后面会再讲。
artifactId 是构件ID这个名称一般都为小写字母没有其他的特殊字符我这里写的有问题大写不会报错也不会影响打包、推送就是不太符合规范推荐使用“实际项目名称模块名称”的方式定义例如spirng-mvn、spring-core等。
如果 gradle 报错出现 main 找不到的情况可以加入下列代码显示的声明路径
sourceSets {main {java { srcDirs [src/java] }resources { srcDir src/resources }}
}licenses 开源协议不必要写如果你的项目不开源的话可以不写。
repositories 下写的是要发布到哪里建议先添加一个 mavenLocal() 发布到本地试试它会发布到 username/.m2/repository/ 目录下确定好没问题再上传 sonatype 上。
https://s01.oss.sonatype.org/content/repositories/releases/
这个地址是发布 release 的地址如果你还要发布其它版本的话可以看看下列的地址
https://s01.oss.sonatype.org/content/groups/public/
https://s01.oss.sonatype.org/content/groups/staging/
https://s01.oss.sonatype.org/content/repositories/snapshots/
这个地址千万不能填错因为 sonatype 更换了新的服务器但是网上的文章都是旧的用的都是旧地址会导致上传有问题。
最后的 signing 一定要写在 publishing 之后不然会出现语法错误。
解决源码混淆问题非商用 SDK 可跳过
事先声明此部分我未解决留下我的解决经验以便后来者可以借鉴减少重复劳动或者减少试错成本。
上传 maven 一般来说需要三样产物release.jar 是打包好的 sdksource.jar 是便于使用者查看源码的 jarjavadoc.jar 是方便使用者看文档和代码上的注释的 jar。
由于我们是商用的 SDK 所以上传时不能上传源码我就想那上传的时候选择性的混淆一下吧外层接口保存原装内部代码混淆一下于是就开始研究怎么过滤这个代码。
task sourcesJar(type: Jar) {from android.sourceSets.main.java.srcDirsclassifier sources
}思路一写一个 gradle plugin
通过一个 gradle plugin 添加一个任务在打 sourceJar 的时候通过一些规则混淆源码。
在项目下新建一个 moudle 他通过使用 gradle 和 javaparser 来处理代码。加入如下依赖
dependencies {// gradle sdkimplementation gradleApi()// groovy sdkimplementation localGroovy()implementation com.android.tools.build:gradle:7.1.3implementation com.github.javaparser:javaparser-core:3.24.2
}这个插件完成之后还要发布到本地然后另一个项目来引用并 apply。
plugins{id groovyid maven-publish
}
afterEvaluate {publishing {publications {maven(MavenPublication) {artifact build/libs/hidesourceplugin.jargroupId com.liuyue.pluginartifactId HideSourcePluginversion 0.0.2}}repositories{mavenLocal()}}
}最简略的发布逻辑接下来处理代码。
import org.gradle.api.Plugin
import org.gradle.api.Projectclass HideSourcePlugin implements PluginProject {Overridevoid apply(Project project) {final android project.extensions.androidHideSourceTask sourcesTask project.tasks.findByName(hideSourceJar) as HideSourceTaskif (sourcesTask null) {sourcesTask project.tasks.create(hideSourceJar, HideSourceTask)}sourcesTask.from(android.sourceSets.main.java.srcDirs)}
}首先它要实现 plugin 的接口重写 applay 的方法当这个插件被 apply 的时候生效。
检查当前任务列表里有没有一个 hideSourceJar 的任务没有的话就创建添加一个然后让它来处理我们源码路径下的所有文件。
import com.github.javaparser.JavaParser
import com.github.javaparser.ast.CompilationUnit
import com.github.javaparser.ast.body.ConstructorDeclaration
import com.github.javaparser.ast.body.MethodDeclaration
import com.github.javaparser.ast.expr.FieldAccessExpr
import com.github.javaparser.ast.expr.MethodCallExpr
import com.github.javaparser.ast.expr.NameExpr
import com.github.javaparser.ast.expr.StringLiteralExpr
import com.github.javaparser.ast.stmt.BlockStmt
import com.github.javaparser.ast.visitor.VoidVisitorAdapter
import org.gradle.jvm.tasks.Jar/*** author moonshoter*/
public class HideSourceTask extends Jar {HideSourceTask() {super()group artifactsclassifier sources-hidefilter(CodeFilterReader.class)}static class CodeFilterReader extends FilterReader {CodeFilterReader(Reader reader) {super(reader)CompilationUnit compilationUnit JavaParser.parse(reader)compilationUnit.accept(new MethodVisitor(), null)String codeAfterHide compilationUnit.toString()this.in new StringReader(codeAfterHide)reader.close()}private static class MethodVisitor extends VoidVisitorAdapterVoid {Overridevoid visit(MethodDeclaration n, Void arg) {// 清除原数据n.removeBody()// 修改BlockStmt block new BlockStmt()n.setBody(block)NameExpr clazz new NameExpr(System)FieldAccessExpr field new FieldAccessExpr(clazz, out)MethodCallExpr call new MethodCallExpr(field, println)call.addArgument(new StringLiteralExpr(Some Unspoken Thing~~))block.addStatement(call)}Overridevoid visit(ConstructorDeclaration n, Void arg) {if (n.body ! null) {n.body.statements.clear()}// 修改BlockStmt block new BlockStmt()n.body blockNameExpr clazz new NameExpr(System)FieldAccessExpr field new FieldAccessExpr(clazz, out)MethodCallExpr call new MethodCallExpr(field, println)call.addArgument(new StringLiteralExpr(Some Unspoken Thing~~))block.addStatement(call)}}}
}这是一个替换方法中的代码为 System.out.println(Some Unspoken Thing~~) 的逻辑想要替换哪些方法可以自己写一个逻辑来控制。
好现在代码写好了publishing 到本地检查本地确实有此插件jar 也正确。 到了应用的时候了先在项目的 build.gradle 中加入 mavenLocal() 和 classpath
buildscript {repositories {mavenLocal()}dependencies {classpath com.liuyue.plugin:HideSourcePlugin:0.0.2}
}**注意**如果你使用的 gradle 是 7.x 的那么你项目的 build.gradle 会变成这个样子
plugins {id com.android.application version 7.2.0-alpha07 apply falseid com.android.library version 7.2.0-alpha07 apply false
}task clean(type: Delete) {delete rootProject.buildDir
}看到这个让我感觉有点不知所措之前这东西不在这的呀然后我发现 setting.gradle 也变了以前只有 include ‘xxx’ 来着现在多了一堆东西。
pluginManagement {repositories {gradlePluginPortal()google()mavenCentral()}
}
dependencyResolutionManagement {repositories {google()mavenCentral()}
}
rootProject.name OpenGLESUtils
include :app
include :library
include :hidesourceplugin仔细对比可以发现原来是原来项目的一些配置移动到了 setting.gradle 中去了那我就在 setting.gradle 中写吧咔咔咔写上去发现它居然报错了
Cannot resolve external dependency com.liuyue.plugin:HideSourcePlugin:0.0.2 because no repositories are defined.我只好再 build.gradle 中写了emmm成功了。
好现在applay 它运行叮~出错了。
Build was configured to prefer settings repositories over project repositories but repository Gradle Libs was added by unknown code它觉得你添加的 gradle libs 是一个未知的来源它不敢用。
真怂它不敢我敢删除 setting.gradle 中的 repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 报错解决搞定。
现在问题拮据了下一步publishingemmm没有用。
Game over~
那我换一种思路吧生成 sourceJar 的时候 from 指定了要生成 jar 包的代码的路径这块是可以写多个的它会自己合并这里还有一个方法叫 filter我能不能用这个过滤做一些操作呢我理想的写法
task sourcesJar(type: Jar) {from android.sourceSets.main.java.srcDirsfilter(HideSourceReader.class)classifier sources
}但这样会报错找不到 HideSourceReader.class 那就解决它
先 import 试试因为 gradle 也是用 java 实现的所以语法差不多试试。
Emmm不行
把这个类打成 jar ,然后在 gradle 中依赖它这样应该能找到了吧试试。
Emmm不行
Gameover~
最后仔细想一想source.jar 它并不是必传的东西所以如果不想暴露源代码可以不传这是我最后的解决方案了。
解决文档 javadoc 问题非商用 SDK 可跳过
事先声明此部分我未解决留下我的解决经验以便后来者可以借鉴减少重复劳动或者减少试错成本。
task javadocJar(type: Jar, dependsOn: Javadoc) {source android.sourceSets.main.java.srcDirsclasspath project.files(android.getBootClasspath().join(File.pathSeparator))classifier javadocfrom javadoc.destinationDir
}这个 task 打出来的 javadoc.jar 正常情况下是这样的 如果没有特殊要求的话那么直接用这个就可以了但我们是商业的 SDK 这种打 jar 的方式会把内部的代码暴露出来已测试。那我们想要的是一个什么样式的呢外部 API 的代码注释使用者可以正常查看内部的代码隐藏或者内部的代码混淆注释清除。
第一点我先注意到了 android.jar 中的 hide 注解只要是被这个修饰的类或者代码段我们平常开发者就无法查看另外提一嘴如果想查看 android 源码的话可以去网上找已经去除 hide 的 android.jar替换本地的就可以了不过某些版本的 AndroidStudio 会检测 jar 的签名会报错 mock jar这个怎么解决自己去找一下吧那我们能不能用 hide 来修饰我们内部的代码呢
怀着激动的心情在我的 demo 工程上试了一下不行
这个东西不是你在注解包里找不到的问题它是普通开发者就无法使用
Game over~
那有没有办法去除掉一些类再打包 javadoc.jar 呢
有exclude 可以指定去除某些类。类似
exclude(com/liuyue/library/haha/**)但是这样写之后会导致 javadoc 执行失败因为依然存在的类可能引用着被去除掉的类这样就会报错。
Game over~
查看 AndroidStudio 自带的打 javadoc 的程序执行的参数试图在打包的时候带上一些参数阻止因为错误导致的打包停止发现没什么特别的暂时无法解决。
Game over~
在这里我还遇到一个坑因为我为了测试打包上传这些功能自己写了一个 demo 工程它写的比较简单然后我写了 4 个类有外部的类有内部的类有混淆的有不混淆的有引用其它类的有单独自己的但是经过混淆后发现就剩两个类了这就让我没法测试内部注释是否可以展示这个问题了左思右想我意识到是混淆的问题因为这里会对代码做优化把它觉得不必要的类没有用的类合并或者删掉所以导致我最后缺了俩类。
一开始我觉得是混淆开启的压缩导致的因为我配置的压缩等级是 5这也是推荐的压缩等级。
-optimizationpasses 5我把它改为 0 发现并不是这样子的然后我查如何关系混淆代码优化发现是这句代码写上这句话可以关闭混淆优化
-dontshrink这个问题会出现在 AndroidStudio 3.4 版本以后因为此版本后都默认开启了 R8 代码缩减。
最后仔细想一想javadoc.jar 它并不是必传的东西所以如果不想暴露源代码可以不传这是我最后的解决方案了。
PGP 签名
在 gradle 的最后一段代码里有这么句
signing {sign configurations.archives
}这句就是签名用的。网上关于 PGP 签名的文章还是很多的从下载到最后生成我都没遇到困难但是到了打包那一步可是坑死我了因为一个签名算法的问题我被迫从头再来。
第一步下载 GPG
Mac 用户可以直接使用 homebrew 下载
brew install gpgWinodws 用户可以在 https://www.gpg4win.org/ 这里下载
第二步生成密钥
gpg --full-gen-key这里会让你选择密钥算法密钥长度密钥有效期 这里一定要选 4 RSA 仅用于签名我也吃了这个的亏不然操作到最后你会发现一个错误
unknown public key algorithm encounteredgradle 会无法理解里的加密算法 随后它会让你写一个名字电子邮件地址信息都确认无误后它会让你输入一个密码。
这个密码一定要记住了以后要用到
操作完后你的密钥就已经被生成了。你可以使用下列命令来查看你已经创建的密钥
gpg --list-keys --keyid-format short–keyid-format shot 可以让你的密钥以短 ID 的形式展示这个后面会用到。 红框内是你的密钥ID它的左上角是你的短ID。这里注意一下左上角有两组数字一个是 ed25519如果这串数字是 ed 开头的那么恭喜你选错密钥加密算法了这种加密算法为 EDDSA 非 RSA 趁早赶紧重来吧。
如果错了可以选择删除这个密钥如果不删除的话后续再生成同样用户名、邮箱的密钥会比较乱很容易分不清。
而且如果你已经进行了下一步那你就再也无法从网络上删掉这个密钥了。
因为现在仍然在工作的绝大多数密钥服务器都是使用的sks密钥服务器(组)其有以下几个特性:
分布式提交的密钥提交至任何一个在sks服务器池的服务都会很快与其他位于sks池的程序同步。通过分布式提高了sks池整体的可用性可靠性和稳定性。不可删除即使你控制着一个sks密钥服务器删除了一个公钥很快就会通过sks的公钥算法同步而想要命令所有的sks池同时删除一个指定的公钥几乎是不可能的。这样可以阻止恶意第三方恶意删除公钥但是也阻止了正常的公钥删除流程。
所以一旦上传至 sks 池将不可能从sks公钥服务器删除公钥 。顶多只能在公钥上面加上一段我从此以后不再信任/使用该证书的声明(又称 吊销密钥) 。所以这一行为也可以作为攻击 sks 服务器的一种手段讲远了。
如果你想吊销一对密钥需要先生成一个吊销证书而如果你只是不想使用了之前的密钥对你可以先将该密钥的信息修改成垃圾信息然后清空所有有效 uid 和所有 subkey 并将截止时间修改为第二天然后上传到公钥服务器。第二天的时候额外上传吊销证书这样可以既保证密钥服务器的信息不乱也可以吊销这个密钥更方便是从来也不上传到密钥服务器。
gpg --gen-revoke 你的密钥 gpg-revoke.asc吊销证书保存地址然后它会问你为什么要吊销的原因你可以选 3 不再使用然后一路确定就可以了。
然后将撤销证书导入本地 GPG 库中撤销本地公钥
gpg --import gpg-revoke.asc(吊销证书的地址)最后把这个密钥上传到公网上去就好了
gpg --send-keys 你的密钥ID过一会你可以使用 search-keys 来搜索你刚才吊销的密钥会发现它的状态已经改变了会在最后有一个(revoked)的标识。
gpg --search-keys 你的密钥ID或者当时设置的name在本地删除公钥和私钥删除公钥和私钥分别有一条命令不过我建议你全部删除执行以下命令
gpg --delete-secret-and-public-key 你的密钥ID这样就完成掉密钥的吊销和删除了
第三步 上传公钥
为了让大家都知道你的公钥以做验证你需要上传的你的密钥只需要下面的一行命令它会自己上传到一个地方然后这个地方的公钥会很快与其它各处地方进行同步很快你的公钥大家就都知道了这个就叫做钥匙环。
gpg --send-keys 你的密钥ID第四步 导出私钥
在 gradle 的最后一步会对上传的包进行签名这里会用到私钥需要配置一个私钥的地址它需要配置在 gradle.properties 文件中也许可以配置在 gradle 脚本中但是我没找到具体的办法。
signing.keyId你的密钥ID
signing.password密钥密码
signing.secretKeyRingFile私钥所在地址keyId 这里需要填写要签名密钥的ID这里要填短ID在第一步的时候讲过如何查看短ID其实就是密钥ID的后8位
gpg --list-keys --keyid-format shortpassword 要填你密钥的密码之前提醒过你要记住记不住的话我也没办法重来吧。
secretKeyRingFile 这里要填私钥的地址一定要是私钥小坑一定要是二进制格式的巨坑。
可以使用下面的命令导出私钥到文件
gpg -o /Users/shaolongfei/Downloads/secring.gpg(这个替换成你的地址) --export-secret-key 你的密钥ID这里一定不要加 -a 或者 -armor 等等的那会使导出的私钥文件是 ascii 编码gradle 不认它会报错使用公钥也会报这个错
It may not be a PGP secret key ring配置完后就可以进行最后一步上传了~
上传
上传最简单了但我建议你先 publish 到本地看一下添加 mavenLocal() 后它会发布到 /username/.m2/repository 文件夹一个正常的发布文件是这样的 写好 gradle 脚本后在 AndroidStudio 的右侧 gradle task 列表里你可以找到 publish 任务 双击执行就可以了或者命令行
./gradlew publish执行过后它就会推送到 sonatype 的 nexus 上去了你可以登录 nexus 查看一下账号密码和你注册 sonatype jira 时一样。
https://s01.oss.sonatype.org/
因为网上很多都是老的文章所以它的地址是老的地址但你依然可以登录界面和新的也完全一样但是登录后它会告诉你账号密码不对或者你没有这个权限就很让人摸不到头脑。
登录上去网上的文章很多都说去 staging Repositories 选项下去找你刚才发布的包它会为 staging 的状态close 后会经过检查最后点击 release 才能真正进行发布。但我发现并不是这样的一开始我也很纳闷为什么我的找不到到底是哪里出问题导致推送失败了也没有报错后来我发现在 nexus 的代码库中是可以搜索到我发布的包的那说明就已经成功了不用担心 过一会你就可以在本地通过 gradle 引用你发布的包了~
mavenCentral 的同步通常是 30 分钟最多可能需要 4 个小时。