Android工程化实践:组件化发布,android离线地图开发


3. 如何发布组件(artifacts)?

========================================================================================

在 Gradle 中发布组件,可以使用以下两个 Maven 插件:

  • Maven Plugin(旧版)

  • Maven Publish Plugin

3.1 发布到本地仓库

我们需要使用 Maven 插件的uploadArchives任务,并且需要指定组件的信息。例如:

模块级 build.gradle

plugins {

id ‘com.android.library’

id ‘kotlin-android’

id ‘maven’

}

uploadArchives {

repositories {

mavenDeployer {

// 发布地址:直接发布到项目本地路径

repository(url: uri(’…/repository’))

// 组件信息:com.pengxr.demo:maven:v1.0.0

pom.groupId = “com.pengxr.demo”

pom.artifactId = “maven”

pom.version = “v1.0.0”

}

}

}

执行 Gradle Sync 之后,就可以在 Gradle 窗口该模块的 Tasks 列表中找到名为uploadArchives的任务。执行任务,完成后项目中会新增一个repository目录,里面就是新发布的组件。

注意事项:

  • 1、升级到 Android Stidio 4.2 之后,如果在 Gradle 栏目中找不到 Task 列表,在设置里取消勾选此项即可:

Android工程化实践:组件化发布,android离线地图开发_第1张图片

  • 2、无法发布应用模块

plugins {

id ‘com.android.application’ // 无法发布应用模块

id ‘kotlin-android’

id ‘maven’

}

3.2 使用 nexus 搭建私有仓库

发布组件到本地仓库只能单机使用,在实际工作中,我们往往需要将组件发布给其他团队成员使用。此时,可以将组件发布到 局域网私有仓库。最常见的私有仓库管理工具是 Nexus [ˈneksəs]。按照以下步骤搭建环境:

  • 1、下载 Nexus 安装包: 这里以 Mac 环境为例:下载地址;

  • 2、启动 Nexus 服务进程: 进入安装路径/nexus-3.30.1-01/bin,在终端运行命令:

./nexus start

./nexus status

输出:nexus is running. 表示启动成功

需要停止服务时,可以执行命令:

./nexus stop

  • 3、浏览器打开 http://127.0.0.1:8081/,进入 Nexus 管理页面

Android工程化实践:组件化发布,android离线地图开发_第2张图片

  • 4、点击右上角 Sign in 登录: 默认账号名是 admin,首次登录会弹窗提示密码的存储位置(根据指示到相应路径下的文件中找到密码复制粘贴过来),登录成功后界面如下:

Android工程化实践:组件化发布,android离线地图开发_第3张图片

这个列表包含了所有的 Nexus 仓库,点击 “Copy” 按钮,可以复制仓库的 URL 地址。其中两个仓库比较常用:

maven-release:策略为 Release 的宿主类型仓库,用于部署内部组件的发布版本;

maven-snapshots:策略为 Shapshot 的宿主类型仓库,用于部署内部组件的快照版本。

类型(Type):group(仓库组)、hosted(宿主)、proxy(代理)和 virtual(虚拟);

格式(Format):maven1、maven2、nuget

  • 5、发布到指定仓库: 在模块级 build.gradle 中增加配置:

模块级 build.gradle

apply plugin: ‘maven’ // Maven 插件

uploadArchives {

repositories {

mavenDeployer {

// url:仓库路径

// userName:账号名

// password:密码

repository(url: “http://127.0.0.1:8081/repository/maven-releases/”){

authentication(userName: “admin”, password: “pengxurui123”)

}

pom.groupId = “com.pengxr.demo”

pom.artifactId = “maven”

pom.version = “v1.0.0”

}

}

}

执行任务,发布成功后可以在 nexus 管理平台上看到新发布的类库:

Android工程化实践:组件化发布,android离线地图开发_第4张图片

  • 6、依赖类库: 在项目级 build.gradle 声明远程仓库,在模块级 build.gradle 中依赖类库。

项目级 build.gradle

allprojects {

repositories {

google()

mavenCentral()

maven { url “http://127.0.0.1:8081/repository/maven-releases/” }

}

}

模块级 build.gradle

dependencies {

implementation ‘com.github.pengxurui:MavenPuhlish:v1.0.4’

}

提示: 当然了,实际项目中 nexus 不可能配置在本机上,而是会配置在局域网服务器中。

3.3 发布到 Github 仓库

如果你需要将开源,那么就需要发布到公共仓库,这一节介绍发布到 Github 的步骤:

  • 1、依赖 Github Maven 插件: 在项目级 build.gradle 中添加插件依赖:

项目级 build.gradle

dependencies {

classpath “com.github.dcendents:android-maven-gradle-plugin:1.5” // // GitHub Maven 插件

}

  • 2、应用 Github Maven 插件: 在发布模块的 build.gradle 中应用插件:

模块级 build.gradle

apply plugin: ‘com.github.dcendents.android-maven’ // GitHub Maven 插件

  • 3、声明 group: 同时在发布模块的 build.gradle 中声明组件的 groupId:

模块级 build.gradle

apply plugin: ‘com.github.dcendents.android-maven’ // GitHub Maven 插件

group = ‘com.github.pengxurui’ // github 的用户名

  • 4、将项目 push 到 Github

  • 5、在 Github 上创建 Release Tag(在本地创建 Tag 再推到 Gtihub 也一样):

Android工程化实践:组件化发布,android离线地图开发_第5张图片

  • 6、将项目上传到 JitPack: 打开 jitpack.io/,将项目链接复制到输入… Look up,等待编译完成。到这里就完成发布了。

Android工程化实践:组件化发布,android离线地图开发_第6张图片

  • 7、依赖类库: 在项目级 build.gradle 声明远程仓库,在模块级 build.gradle 中依赖类库。

项目级 build.gradle

allprojects {

repositories {

google()

mavenCentral()

maven { url “https://jitpack.io” }

}

}

模块级 build.gradle

dependencies {

implementation ‘com.github.pengxurui:MavenPuhlish:v1.0.4’

}

踩坑记录:

  • 模块 build.gradle 中应用了 Github Maven 插件后,要去掉 uploadArchives 任务,否则构建会报错。

Exception is:

java.lang.IllegalAccessError: tried to access method org.gradle.api.internal.artifacts.DefaultModuleVersionIdentifier.(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V from class org.gradle.api.plugins.AndroidMavenPlugin$8

3.4 指定发布二进制文件

使用新版 Maven 插件,可以直接以指定二进制文件的方式发布组件。例如:

apply plugin: ‘maven-publish’

publishing {

publications {

任务名 {

groupId MAVEN_GROUP_ID

artifactId MAVEN_ARTIFACTID

version MAVEN_VERSION

artifact([文件路径])

}

}

repositories {

maven {

// 发布仓库路径

url MAVEN_RELEASE_URL

}

}

}


4. 实战应用

==========================================================================

4.1 封装通用发布脚本

随着项目组件化程度加深,越来越多组件需要发布到 Maven 仓库,此时就很有必要将 Maven 发布能力封装为一个通用脚本,步骤如下:

  • 步骤 1:封装发布脚本:

maven.gradle

apply plugin: ‘maven’

uploadArchives {

repositories {

mavenDeployer {

// 是否快照版本

def isSnapShot = Boolean.valueOf(MAVEN_IS_SNAPSHOT)

def versionName = MAVEN_VERSION

if (isSnapShot) {

versionName += “-SNAPSHOT”

}

// 组件信息

pom.groupId = MAVEN_GROUP_ID

pom.artifactId = MAVEN_ARTIFACTID

pom.version = versionName

// 快照仓库路径

snapshotRepository(url: uri(MAVEN_SNAPSHOT_URL)) {

authentication(userName: MAVEN_USERNAME, password: MAVEN_USERNAME)

}

// 发布仓库路径

repository(url: uri(MAVEN_RELEASE_URL)) {

authentication(userName: MAVEN_USERNAME, password: MAVEN_USERNAME)

}

println("###################################"

  • "\nuploadArchives = " + pom.groupId + “:” + pom.artifactId + “:” + pom.version + “.” + pom.packaging

  • “\nrepository =” + (isSnapshot ? MAVEN_SNAPSHOT_URL : MAVEN_RELEASE_URL)

  • “\n###################################”

)

}

}

}

这段脚本会读取 MAVEN_IS_SNAPSHOT 配置参数,如果为 true,会在版本号后追加 -SNAPSHOT 后缀,表示快照版本。随后声明了两个仓库:repository(…) 声明的是 Release 仓库地址,而 snapshotRepository(…) 声明的是快照仓库地址。Maven 会自动将版本号带 -SNAPSHOT 后缀的组件发布到 snapshotRepository(…) 仓库中,这样就 自动将正式版本和快照版本分发的不同仓库中。

当然了,不用 snapshotRepository(…) 也有办法实现:

def url = isSnapShot ? MAVEN_SNAPSHOT_URL : MAVEN_RELEASE_URL

repository(url: url) {

authentication(userName: MAVEN_USERNAME, password: MAVEN_USERNAME)

}

  • 步骤 2:声明项目级配置参数:

项目级 gradle.properties

MAVEN_SNAPSHOT_URL = /Users/pengxurui/workspace/public/DemoHall/snapshotRepository

MAVEN_RELEASE_URL = /Users/pengxurui/workspace/public/DemoHall/releaseRepository

MAVEN_USERNAME =

MAVEN_PASSWORD =

MAVEN_IS_SNAPSHOT = true

MAVEN_GROUP_ID = com.pengxr.demo

| 参数 | 描述 |

| :-- | :-- |

| MAVEN_SNAPSHOT_URL | 快照仓库地址 |

| MAVEN_RELEASE_URL | 发布仓库地址 |

| MAVEN_USERNAME | 仓库账号 |

| MAVEN_PASSWORD | 仓库密码 |

| MAVEN_IS_SNAPSHOT | 是否快照版本 |

| MAVEN_GROUP_ID | 组织 / 公司的名称 |

| MAVEN_ARTIFACTID | 组件的名称(在发布模块配置) |

| MAVEN_VERSION | 组件的版本(在发布模块配置) |

  • 步骤 3:在发布模块应用脚本

模块级 build.gradle

apply from: ‘…/maven.gradle’

  • 步骤 4:在发布模块配置参数 (模块级配置参数会覆盖项目级配置参数)

模块级 gradle.properties

MAVEN_ARTIFACTID = maven

MAVEN_VERSION = v1.0.0

MAVEN_IS_SNAPSHOT = true

完成以上步骤并 Sync 后,就可以在 Gradle 窗口中该模块下找到 uploadArchives 任务,执行发布:

输出:

Executing tasks: [uploadArchives] in project /Users/pengxurui/workspace/public/DemoHall/MavenPublish/lib

Configure project :lib

###################################

uploadArchives = com.pengxr.demo:maven:v1.0.0-SNAPSHOT.jar

repository =/Users/pengxurui/workspace/public/DemoHall/snapshotRepository

###################################

Task :lib:preBuild UP-TO-DATE

  • 步骤 5:依赖组件: 在项目级 build.gradle 中声明依赖仓库,在模块级 build.gradle 中声明依赖:

项目级 build.gradle

allprojects {

repositories {

maven { url MAVEN_RELEASE_URL }

maven { url MAVEN_SNAPSHOT_URL }

}

}

模块级 build.gradle

dependencies {

implementation “com.pengxr.demo:maven:v1.0.0+”

}

其中,版本号 v1.0.0+ 中的 “+” 号表示依赖最大的版本号,优先正式版本。比如远程仓库中存在 v1.0.0,v1.0.0.1,v1.0.0.1-SNAPSHOT 三个类库,那么 v1.0.0+ 依赖的是其 v1.0.0.1。

+ 号和 -SNAPSHOT 的区别?

  • 号影响类库版本的选择,而 -SNAPSHOT 影响是否向远程仓库更新最新版本。

完整代码和演示工程你可以直接下载查看: MavenPublish 下载路径。Demo 里配置的仓库都为本地仓库,在实际项目中,你需要替换为你公司内的私有仓库。

4.2 引用本地 aar 包

有时候,我们直接依赖第三方或第二方提供的 aar 文件。例如:

  • aarlib

\ libs

  • lib-debug-aar

  • build.gradle // api(name: ‘lib-debug’, ext: ‘aar’)

输出:Unable to resolve dependency for ‘:aarlib@debugUnitTest/compileClasspath’: Could not resolve :lib-debug.

但是,这样并不能成功依赖。你需要 build.gradle 文件中声明 aar 的 Flat Directory 仓库地址。你可以放在 android{} 节点内,或者直接放在根节点,效果是一样的。例如:

aarlib 模块 build.gradle

dependencies {

api(name: ‘lib-debug’, ext: ‘aar’)

如何做好面试突击,规划学习方向?

面试题集可以帮助你查漏补缺,有方向有针对性的学习,为之后进大厂做准备。但是如果你仅仅是看一遍,而不去学习和深究。那么这份面试题对你的帮助会很有限。最终还是要靠资深技术水平说话。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。建议先制定学习计划,根据学习计划把知识点关联起来,形成一个系统化的知识体系。

学习方向很容易规划,但是如果只通过碎片化的学习,对自己的提升是很慢的。

我搜集整理过这几年字节跳动,以及腾讯,阿里,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节

img

在搭建这些技术框架的时候,还整理了系统的高级进阶教程,会比自己碎片化学习效果强太多。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

你可能感兴趣的:(程序员,架构,移动开发,android)