创建和发布 Android 开发库的终极指南

简介:

相关术语介绍

在我们开始之前,还有一些术语,需要熟悉下。

项目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 中央仓库中。

将开发库的核心代码和示例代码区分开来。在我的项目中,我将他们分成 library 和 sample 两个模块。请仔细阅读关于创建一个开发库模块的技巧。你也可能需要重命名你的模块

在 sample 模块的 build.gradle 文件中,请确保包含以下内容:


 
 
  1. apply plugin: 'com.android.application'
  2. dependencies {
  3. compile project(':library')
  4. }

在 library 模块的 build.gradle 文件中,请确保包含以下内容: 


 
 
  1. apply plugin: 'com.android.library'
  2. apply from: 'maven-push.gradle'

在 library 模块中,增加 gradle.properties 文件,请确保在该文件中包含以下内容:


 
 
  1. POM_NAME=ProjectName
  2. POM_ARTIFACT_ID=projectname
  3. POM_PACKAGING=aar

在 library 模块中,增加 maven-push.gradle 文件,请确保在该文件中包含以下内容: 


 
 
  1. /*
  2. * Copyright 2013 Chris Banes
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. apply plugin: 'maven'
  17. apply plugin: 'signing'
  18. def isReleaseBuild() {
  19. return VERSION_NAME.contains("SNAPSHOT") == false
  20. }
  21. def getReleaseRepositoryUrl() {
  22. return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL
  23. : "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
  24. }
  25. def getSnapshotRepositoryUrl() {
  26. return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL
  27. : "https://oss.sonatype.org/content/repositories/snapshots/"
  28. }
  29. def getRepositoryUsername() {
  30. return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : ""
  31. }
  32. def getRepositoryPassword() {
  33. return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : ""
  34. }
  35. afterEvaluate { project ->
  36. uploadArchives {
  37. repositories {
  38. mavenDeployer {
  39. beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
  40. pom.groupId = GROUP
  41. pom.artifactId = POM_ARTIFACT_ID
  42. pom.version = VERSION_NAME
  43. repository(url: getReleaseRepositoryUrl()) {
  44. authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
  45. }
  46. snapshotRepository(url: getSnapshotRepositoryUrl()) {
  47. authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
  48. }
  49. pom.project {
  50. name POM_NAME
  51. packaging POM_PACKAGING
  52. description POM_DESCRIPTION
  53. url POM_URL
  54. scm {
  55. url POM_SCM_URL
  56. connection POM_SCM_CONNECTION
  57. developerConnection POM_SCM_DEV_CONNECTION
  58. }
  59. licenses {
  60. license {
  61. name POM_LICENCE_NAME
  62. url POM_LICENCE_URL
  63. distribution POM_LICENCE_DIST
  64. }
  65. }
  66. developers {
  67. developer {
  68. id POM_DEVELOPER_ID
  69. name POM_DEVELOPER_NAME
  70. }
  71. }
  72. }
  73. }
  74. }
  75. }
  76. signing {
  77. required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
  78. sign configurations.archives
  79. }
  80. //task androidJavadocs(type: Javadoc) {
  81. //source = android.sourceSets.main.allJava
  82. //}
  83. //task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
  84. //classifier = 'javadoc'
  85. //from androidJavadocs.destinationDir
  86. //}
  87. task androidSourcesJar(type: Jar) {
  88. classifier = 'sources'
  89. from android.sourceSets.main.java.sourceFiles
  90. }
  91. artifacts {
  92. archives androidSourcesJar
  93. }
  94. }

修改在项目根目录的 .gitignore 文件 


 
 
  1. # [Android] ========================
  2. # Built application files
  3. *.apk
  4. *.ap_
  5. # Files for the Dalvik VM
  6. *.dex
  7. # Java class files
  8. *.class
  9. # Generated files
  10. bin/
  11. gen/
  12. # Gradle files
  13. .gradle/
  14. build/
  15. # Local configuration file (sdk path, etc)
  16. local.properties
  17. # Proguard folder generated by Eclipse
  18. proguard/
  19. # Log Files
  20. *.log
  21. ## Directory-based project format:
  22. .idea/
  23. ## File-based project format:
  24. *.ipr
  25. *.iws
  26. ## Plugin-specific files:
  27. # IntelliJ
  28. out/
  29. # mpeltonen/sbt-idea plugin
  30. .idea_modules/
  31. # JIRA plugin
  32. atlassian-ide-plugin.xml
  33. # Crashlytics plugin (for Android Studio and IntelliJ)
  34. com_crashlytics_export_strings.xml
  35. # [Maven] ========================
  36. target/
  37. pom.xml.tag
  38. pom.xml.releaseBackup
  39. pom.xml.versionsBackup
  40. pom.xml.next
  41. release.properties
  42. # [Gradle-Android] ========================
  43. # Ignore Gradle GUI config
  44. gradle-app.setting
  45. # Gradle Signing
  46. signing.properties
  47. trestle.keystore
  48. # Mobile Tools for Java (J2ME)
  49. .mtj.tmp/
  50. # Package Files #
  51. *.jar
  52. *.war
  53. *.ear
  54. # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
  55. hs_err_pid*
  56. # Misc
  57. /.idea/workspace.xml
  58. .DS_Store
  59. /captures
  60. **/*.iml
  61. *.class

修改在项目根目录的 settings.gradle 文件 


 
 
  1. include ':sample', ':library'

修改在项目根目录的 gradle.properties 文件


 
 
  1. # Project-wide Gradle settings.
  2. # IDE (e.g. Android Studio) users:
  3. # Gradle settings configured through the IDE *will override*
  4. # any settings specified in this file.
  5. # For more details on how to configure your build environment visit
  6. # http://www.gradle.org/docs/current/userguide/build_environment.html
  7. # Specifies the JVM arguments used for the daemon process.
  8. # The setting is particularly useful for tweaking memory settings.
  9. # Default value: -Xmx10248m -XX:MaxPermSize=256m
  10. # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
  11. # When configured, Gradle will run in incubating parallel mode.
  12. # This option should only be used with decoupled projects. More details, visit
  13. # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
  14. # org.gradle.parallel=true
  15. VERSION_NAME=0.0.1
  16. VERSION_CODE=1
  17. GROUP=com.github.github_username
  18. POM_DESCRIPTION=A library that does X, Y, and Z
  19. POM_URL=https://github.com/github_username/ProjectName
  20. POM_SCM_URL=https://github.com/github_username/ProjectName
  21. POM_SCM_CONNECTION=scm:git@github.com:github_username/ProjectName.git
  22. POM_SCM_DEV_CONNECTION=scm:git@github.com:github_username/ProjectName.git
  23. POM_LICENCE_NAME=The Apache Software License, Version 2.0
  24. POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
  25. POM_LICENCE_DIST=repo
  26. POM_DEVELOPER_ID=github_username
  27. POM_DEVELOPER_NAME=GitHub FullName

增加 README.md 文件,向其他开发者介绍你的开发库以及如何使用它。如果你想在你的 README.md 文件中增加些截图,我极力推荐一款叫做Screenr的app。 

安装 GPG

如果你的机器上还没安装 GPG,你需要下载安装它。如果你是 MacOSX 系统,安装手册在这里。

如果你从未使用过 GPG – 首先,请创建 GPG 密钥:


 
 
  1. $ gpg --gen-key

接下来,找到你的密钥 ID:在你创建 GPG 密钥的时候,如果你不确定该如何回答问题, 这篇指南(Creating an encryption key)可以帮上忙。


 
 
  1. $ gpg --list-keys

现在,发布你的密钥:第一行像是 pub XXXXX/YYYYYYYY <日期>的。切记,’YYYYYYYY’ 部分,就是你的密钥 ID。


 
 
  1. $ gpg --keyserver hkp://keyserver.ubuntu.com --send-keys YYYYYYYY
  2. $ gpg --keyserver hkp://pgp.mit.edu --send-keys YYYYYYYY

你当然也可以使用其他密钥服务器,你也可以通过如下命令确认你的密钥是否已经发布:


 
 
  1. $ gpg --keyserver hkp://pgp.mit.edu --search-keys johndoe@example.com # 使用你的邮箱

为了使你的开发库在 Gradle, Please网站上列出(也为了其他人方便的引用你的开发库),请上传你的项目到 Maven Central。 最简单的上传项目的方法是使用 Sonatype

Sonatype

  1. Sonatype 创建一个 JIRA 帐号。
  2. 登录成功后,创建一个 new issue

我为我的 Trestle 项目创建了一个 GitHub 仓库。所以我在 new issue 上填写的字段大概如此:

Group Id : com.github.<github_username>

Project URL : https://github.com/<github_username>/<project_name>

SCM url : https://github.com/<github_username>/<project_name>.git

Username : <sonatype_username>

Already Synced to Central : No

注意:我在你需要填写的字段上增加了括号作为占位符。你需要将它们替换成合适的值。

当你准备提交 issue 的时候,issue 的细节应该要和上面的截图差不多。当你提交完成后,Sonatype 将用 2 个工作日来处理你的 issue。接着,你将收到一份确认邮件,告知你的配置已经准备好了,你可以发布你的开源库了。

不要部署你的开源库,直到你接收到一封表明你的票据已经 OK 了的邮件。 对新项目来说,一个通病就是过早的部署。这将会误使你的构件(artifacts)变成一个人人都能获得的仓库。

最后,如果你的组件已经在中央仓库中了,请在你的票据中添加以下信息,并参考这篇文章,如何迁移到 OSSRH

修改你本机上的 ~/.gradle/gradle.properties 文件,包含以下内容:


 
 
  1. NEXUS_USERNAME=sonatype_username
  2. NEXUS_PASSWORD=sonatype_password
  3. signing.keyId=gpg_key_id
  4. signing.password=gpg_password
  5. signing.secretKeyRingFile=/Users/username/.gnupg/secring.gpg
  6. org.gradle.daemon=true

当你发布开发库的时候,身份认证信息已经在 gradle.properties 文件中提供了。请确保提供了正确的 nexus 用户名和密码(也就是 Sonatype 的用户名和密码),否则你将得到未授权的 401 错误

注意:如果你之前已经发布过一个开发库,那么你不需要在 JIRA(Sonatype) 上创建一个新的 issue。每个顶级的 groupId 对应一个 JIRA issue。你应该已经有了部署任何新构件到你的 groupId 或者下属 group 应需要的所有权限。中央仓库的同步操作遵循从上到下的过程,所以任何下属组的发布版本都将会自动同步。当你发布新组件,你不需要告诉 Sonatype,因为当你进行仓库同步工作的时候,没有什么需要 Sonatype 去配置或者检查的, Sonatype 仅仅会在第一次进行同步操作的时候,发布一条 twitter。

发布

一旦你准备发布你的开发库,在 Android Studio 中, 打开右侧的 Gradle 视图,在 Tasksupload 下,点击 uploadArchives,将会上传你的开发库到 Sonatype Staging Repositories

在 Sonatype Staging Repositories 网页上,登陆你的 Sonatype 账号,查找你的 “staging” 开发库,它应该在列表的最后,选中它,并按下 “关闭” 按钮。关闭一个开发库实际上意味着你准备发布它。如果关闭操作一切顺利 – 你应该会看到一个激活了的 ‘发布’ 按钮。你可能需要刷新下页面。请按下发布按钮。请阅读关于使用 Nexus 管理仓库的帮助文档。如果这是你发布的第一个开发库,返回到 JIRA,在 JIRA 上发表一条你已经改进了你的开发库的评论,如果不是第一个,就没必要告诉 Sonatype 你改进了你的开发库。然后,你应该会收到来自 Sonatype 的一条回复信息,信息上说你的开发库在 10 分钟内能准备好,将会在接下来的几个小时同步到 Maven 中央仓库。几个小时之后,它将展示在 Gradle, Please 网站上。

原文发布时间为:2016-05-28

本文来自云栖社区合作伙伴“Linux中国”

相关文章
|
4天前
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
51 19
|
1月前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
69 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
1月前
|
数据采集 JavaScript Android开发
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
58 7
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
1月前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
182 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
1月前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
58 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
2月前
|
缓存 前端开发 Android开发
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
117 12
【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
|
1月前
|
安全 Android开发 iOS开发
escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥
escrcpy 是一款基于 Scrcpy 的开源项目,使用 Electron 构建,提供图形化界面来显示和控制 Android 设备。它支持 USB 和 Wi-Fi 连接,帧率可达 30-120fps,延迟低至 35-70ms,启动迅速且画质清晰。escrcpy 拥有丰富的功能,包括自动化任务、多设备管理、反向网络共享、批量操作等,无需注册账号或广告干扰。适用于游戏直播、办公协作和教育演示等多种场景,是一款轻量级、高性能的 Android 控制工具。
|
2月前
|
Dart 前端开发 Android开发
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
46 1
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
3月前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
87 19
|
3月前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
111 14

热门文章

最新文章