为Android组件化项目搭建Maven私服

概览

文章目录

      • 概览
      • 前言
      • 搭建 maven 私服
        • 服务器环境
        • jdk安装配置
        • nexus安装配置
        • 管理创建存储点、仓库
      • 项目中使用 maven 私服
        • 上传 module 到仓库
          • 自动发布 module
          • 手动上传单个aar包
        • 引用仓库中的 module
          • build.gradle引入远程module
      • FAQ
        • 开发阶段有些module用远程依赖,有些module用本地依赖,造成BuildConfig中DEBUG环境变量不一致?
        • 发布的组件中远程依赖引用不到了?
        • 引用的第三方aar无需根据编译环境分别打包正式/测试版,如何处理?
      • 参考链接

前言

本文根据网络上的文章以及个人实践,综合整理而成。
做这件事的目的,是为了缩短APP的编译时间。
记得接手公司项目的时候,项目已经使用了当时流行的组件化方案,当时项目刚起步,组件不多,比较轻量化,编译一次正式版用时大概五分钟左右。这几年随着项目和技术的发展,组件化方案中间重构更换了一次,项目中的组件也发展到了二十多个,现在编译一次正式版,不算加固时间,用时十七分钟左右。
开发调试阶段目前也饱受困扰。由于所有组件都依赖base_lib,只要base中改了一个字符,debug调试编译时所有组件就会重新编译一遍,及其浪费时间。

搭建 maven 私服

要正常安装使用 maven 私服,需要几个前置条件,如果你的服务器都满足的话,可以跳过这几个配置:

  • 根据nexus需求,安装合适的 java 环境
  • 安装合适的 nexus 版本
  • 打开服务器8081端口,用以支持在浏览器访问nexus管理页面
服务器环境
jdk安装配置

Download jdk 11这里我下载的是Linux x64 Compressed Archive-jdk-11.0.22这个版本
在这里插入图片描述

  1. 使用sftp上传到服务器/opt/jdk目录
    在这里插入图片描述

  2. 解压到当前目录

    cd /opt/jdk
    tar -zxvf jdk-11.0.22_linux-x64_bin.tar.gz
    

    在这里插入图片描述

  3. 使用sftp修改环境配置文件:/etc/profile

    #jdk config(在文档结尾插入)
    export JAVA_HOME=/opt/jdk/jdk-11.0.22
    export PATH=$PATH:$JAVA_HOME/bin
    export CLASSPATH=.:$JAVA_HIOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    

    在这里插入图片描述

  4. 重启 /etc/profile 使之重新生效:

    source /etc/profile
    
  5. 验证 JDK 是否安装成功

    java --version
    

    在这里插入图片描述

nexus安装配置

Download Sonatype Nexus Repository根据安装的java版本选择对应的安装包,这里我下载的是/nexus-3.68.1-02-java11-unix这个版本,对应java11
在这里插入图片描述

  1. 使用sftp上传到服务器/opt/nexus目录

  2. 解压到当前目录

    cd /opt/nexus
    tar -zxvf nexus-3.68.1-02-java11-unix.tar.gz
    

    在这里插入图片描述

  3. 使用sftp编辑配置文件/opt/nexus/nexus-3.68.1-02/bin/nexus.rc

    run_as_user="root"
    

    在这里插入图片描述

  4. 查看并开放8081端口

    # 查看防火墙某个端口是否开放
    firewall-cmd --query-port=8081/tcp
    # 开放防火墙端口 8081
    firewall-cmd --add-port=8081/tcp --permanent
    # 重新加载防火墙规则
    firewall-cmd --reload
    # 再次查看防火墙某个端口是否开放
    firewall-cmd --query-port=8081/tcp
    

    在这里插入图片描述

  5. 进入bin目录启动nexus

    cd /opt/nexus/nexus-3.68.1-02/bin
    ./nexus start
    

    在这里插入图片描述

  6. 浏览器进入管理页面,http://[服务器ip]:8081
    在这里插入图片描述

  7. 登录账号,admin 的密码在/opt/nexus/sonatype-work/nexus3/admin.password文件中
    在这里插入图片描述

管理创建存储点、仓库
  1. 创建存储点
    默认存储点是default,你也可以直接用默认的,不创建新的
    登录账号,依次进入Setting->Repository->Blob Stores
    在这里插入图片描述

  2. 创建仓库
    在创建仓库前,先介绍一下仓库的三种存储类型Release、Snapshot和Mixed,创建仓库时会使用到
    Release(正式版): 正式版,适合项目稳定后正式发布使用,特性看下面的原理简介。
    Snapshot(快照版): 快照版,适合项目在开发调试中使用,特性看下面的原理简介。
    Mixed(混合版): 可包含release和snapshot版本

    ReleaseSnapshot的原理简介:
    它们的主要区别在于本地获取这些依赖的机制不同。

    • 对于Release版本的项目: 当项目中添加了一个正式版的version为x的依赖时,构建工具在构建项目时会从远程仓库中下载这个version为x的依赖到本地仓库缓存起来,下次再构建项目时,构建工具会从本地仓库中查找是否存在这个version为x的依赖,存在就不会在去远程仓库中拉取。这种特性会导致在团队开发中,如果你发布一个正式版的项目时,仍然使用的是同一个version,就可能出现其他使用这个version项目的成员根本接收不到项目的最新变更,这是糟糕的,为了生命安全,大家尽量不要这么做。所以,在每次发布正式版项目时,必须更新version。
    • 对于Snapshot版本的项目: 当项目中添加了一个快照版的version为x的依赖时,不管本地仓库中是否存在这个version为x的依赖,构建工具都会尝试从远程仓库中查看这个version为x的依赖是否最新。这样就能保证团队开发时,所有使用这个version为x的依赖的项目都能获取到依赖最新的变更,而且不用不停的迭代依赖的version。最后一还有一点,Snapshot版项目发布时的version一定要以-SNAPSHOT结尾,英文字母必须大写。

    依次进入Setting->Repository->Repositories
    在这里插入图片描述
    在这里插入图片描述

项目中使用 maven 私服

上传 module 到仓库
自动发布 module
  1. 在module的 build.gradle 同级创建publish.gradle

    apply plugin: "maven-publish"afterEvaluate {def ext = rootProject.extpublishing {publications {release(MavenPublication) {groupId 'com.wln100.future'artifactId 'fragmentation'version '1.0.0-SNAPSHOT'if (isAndroidEnv(project)) {from project.components.release} else {from project.components.java}pom {name = 'fragmentation'description = 'fragmentation'url = ext.nexusMavenUrl}}}repositories {maven {allowInsecureProtocol trueurl = ext.nexusMavenUrlcredentials {username ext.nexusMavenUsernamepassword ext.nexusMavenPassword}}}}
    }static def isAndroidEnv(Project project) {return project.getPlugins().hasPlugin('com.android.application') || project.getPlugins().hasPlugin('com.android.library')
    }
    
  2. 在 module 的 build.gradle 引入 publish.gradle

    apply plugin: 'com.android.library'...
    android {compileSdk compileVersiondefaultConfig {...}buildTypes {...}...}dependencies {...
    }
    //引入自动发布gradle
    apply from: project.file('publish.gradle')
    
  3. 同步代码,运行GradleTask
    在这里插入图片描述

  4. 之后在仓库管理页面可以看到上传成功的module
    在这里插入图片描述

手动上传单个aar包
  1. 管理页面进入Upload->android-examonline-hosted
    在这里插入图片描述

  2. 上传aar,填写必要参数
    在这里插入图片描述
    在这里插入图片描述

引用仓库中的 module

首先需要在项目级的build.gradle中添加仓库地址:

buildscript {...repositories {//本地私服仓maven {allowInsecureProtocol trueurl 'http://[服务器ip]:8081/repository/[仓库名称]/'}...}...
}
...
allprojects {repositories {//本地私服仓maven {allowInsecureProtocol trueurl 'http://[服务器ip]:8081/repository/[仓库名称]/'}...}
}
...
build.gradle引入远程module
dependencies {//引入组件module  api 'com.wln100.future:fragmentation:1.0.0-SNAPSHOT'//引入单个aarapi 'me.yokeyword.fragmentation:fragmentation_core:1.0'
}

FAQ

开发阶段有些module用远程依赖,有些module用本地依赖,造成BuildConfig中DEBUG环境变量不一致?

我的解决方式为,发布module时,分别发布debug和release两包到两个仓库中;引入依赖时,根据编译命令动态切换对应的私服仓库:

  1. 发布时分别发布debug和release
    //publish.gradle
    afterEvaluate {publishing {publications {release(MavenPublication) {...if (isAndroidEnv(project)) {//打包release modulefrom project.components.release} else {from project.components.java}...}debug(MavenPublication) {...if (isAndroidEnv(project)) {//打包debug modulefrom project.components.debug} else {from project.components.java}...}}repositories {maven {allowInsecureProtocol true//根据编译任务动态设置发布仓库if (isReleaseBuild()) {url = NEXUS_URL} else {url = NEXUS_DEBUG_URL}...}}}// 定义一个函数来判断是否为release版本
    def isReleaseBuild() {def taskNames = gradle.startParameter.taskNamesprintln "isReleaseBuild>>>>taskNames:$taskNames"return taskNames.any { it.toLowerCase().contains("release") }
    }
  2. 项目根目录build.gradle动态设置仓库
    //project build.gradle
    ...
    allprojects {apply from: "$rootDir/gradle/maven-utils.gradle"repositories {...//本地私服仓-自有组件maven {allowInsecureProtocol trueif (isReleaseBuild()) {url NEXUS_URL} else {url NEXUS_DEBUG_URL}}google()...maven { url 'https://jitpack.io' }}
    }
    
发布的组件中远程依赖引用不到了?

发布时配置发布参数withxml

afterEvaluate {publishing {publications {release(MavenPublication) {...pom {...withXml {def dependenciesNode = asNode().getAt('dependencies')[0] ?:asNode().appendNode('dependencies')configurations.api.getDependencies().each {dep -> addDependency(project, dependenciesNode, dep, "compile")}configurations.implementation.getDependencies().each {dep -> addDependency(project, dependenciesNode, dep, "runtime")}}}}debug(MavenPublication) {...pom {...withXml {def dependenciesNode = asNode().getAt('dependencies')[0] ?:asNode().appendNode('dependencies')configurations.api.getDependencies().each {dep -> addDependency(project, dependenciesNode, dep, "compile")}configurations.implementation.getDependencies().each {dep -> addDependency(project, dependenciesNode, dep, "runtime")}}}}}...}
}private void addDependency(Project project, def dependenciesNode, Dependency dep, String scope) {if (dep.group == null || dep.version == null || dep.name == null || dep.name == "unspecified") {return}if (dep.version == 'unspecified') {return}final dependencyNode = dependenciesNode.appendNode('dependency')dependencyNode.appendNode('scope', scope)dependencyNode.appendNode('groupId', dep.group)dependencyNode.appendNode('artifactId', dep.name)dependencyNode.appendNode('version', dep.version)println("publish -> library <${dep.group}:${dep.name}:${dep.version}>")if (!dep.transitive) {// In case of non transitive dependency,// all its dependencies should be force excluded from them POM filefinal exclusionNode = dependencyNode.appendNode('exclusions').appendNode('exclusion')exclusionNode.appendNode('groupId', '*')exclusionNode.appendNode('artifactId', '*')} else if (!dep.properties.excludeRules.empty) {// For transitive with exclusions, all exclude rules should be added to the POM filefinal exclusions = dependencyNode.appendNode('exclusions')dep.properties.excludeRules.each { ExcludeRule rule ->final exclusionNode = exclusions.appendNode('exclusion')exclusionNode.appendNode('groupId', rule.group ?: '*')exclusionNode.appendNode('artifactId', rule.module ?: '*')}}
}
引用的第三方aar无需根据编译环境分别打包正式/测试版,如何处理?

新建一个专门存放三方aar库的私服仓库,单独上传依赖三方aar。

//project build.gradle
...
allprojects {apply from: "$rootDir/gradle/maven-utils.gradle"repositories {//本地私服仓-三方libmaven{allowInsecureProtocol trueurl 'http://x.x.x.x:8081/repository/android-third-lib-hosted/'}...google()...}
}

参考链接

Centos开放端口以及查看端口和防火墙配置命令
centos7下搭建nexus
CentOS 7 安装 JDK11(注意版本号要与自己的版本一致)
centos7安装Nexus(Maven私服)与配置使用教程
【github】Blankj/AndroidUtilCode-publish.gradle

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/343322.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python tqdm怎么安装

tqdm是一个显示循环的进度条的库。taqadum, تقدّم&#xff09;在阿拉伯语中的意思是进展。tqdm可以在长循环中添加一个进度提示信息&#xff0c;用户只需要封装任意的迭代器 tqdm(iterator)&#xff0c;是一个快速、扩展性强的进度条工具库。 tqdm库的安装 在CMD窗口下输…

神经网络 torch.nn---Containers

torch.nn — PyTorch 2.3 documentation torch.nn - PyTorch中文文档 (pytorch-cn.readthedocs.io) nn是Neural Network的简称&#xff0c;帮助程序员方便执行如下的与神经网络相关的行为&#xff1a; &#xff08;1&#xff09;创建神经网络 &#xff08;2&#xff09;训练…

redis学习路线

待更新… 一、nosql讲解 1. 为什么要用nosql&#xff1f; 用户的个人信息&#xff0c;社交网络&#xff0c;地理位置&#xff0c;自己产生的数据&#xff0c;日志等等爆发式增长&#xff01;传统的关系型数据库已无法满足这些数据处理的要求&#xff0c;这时我们就需要使用N…

Vxe UI vxe-table 实现自定义列拖拽,列拖拽排序功能

Vxe UI vue vxe-table 实现自定义列拖拽&#xff0c;列拖拽排序功能 开启自定义列 vxe-toolbar 工具栏&#xff0c;通过 custom 启用后就可以开启自定义列功能 <template><div><vxe-toolbar ref"toolbarRef" custom></vxe-toolbar><vx…

k8s 配置资源管理

一、Secret的资源配置 1.1 Secret配置的相关说明 Secret 是用来保存密码、token、密钥等敏感数据的 k8s 资源&#xff0c;这类数据虽然也可以存放在 Pod 或者镜像中&#xff0c;但是放在 Secret 中是为了更方便的控制如何使用数据&#xff0c;并减少暴露的风险。 有四种类型&a…

生活使用英语口语柯桥外语学校成人英语学习

● “自来水”英语怎么说&#xff1f; ● “自来水”的英语表达是&#xff1a;Running water或者Tap water. 例句&#xff1a; There are hot and cold running water in all the bedrooms. 所有的卧室里都有冷热自来水。 ● “热水”英文怎么水&#xff1f; ● 我们不管…

Java面试题:Redis持久化问题

Redis持久化问题 RDB (Redis Database Backup File) Redis数据快照 将内存中的所有数据都记录到磁盘中做快照 当Redis实例故障重启时,从磁盘读取快照文件恢复数据 使用 save/bgsave命令进行手动快照 save使用主进程执行RDB,对所有命令都进行阻塞 bgsave使用子进程执行R…

21 - 即时食物配送 II(高频 SQL 50 题基础版)

21 - 即时食物配送 II -- sum(if(order_datecustomer_pref_delivery_date,1,0))/count(*)sum(order_datecustomer_pref_delivery_date)/count(*) -- count(*),表示数据的行数&#xff0c;如果有分组&#xff0c;为分组后数据的行数select round(100*sum(if(order_datecustomer_…

Gradio.NET:一个快速制作演示demo网页的利器

Gradio介绍 Gradio是一个用于创建机器学习模型交互界面的Python库。它允许开发者快速为他们的模型创建一个简单的web界面&#xff0c;以便于非技术用户和其他开发者进行交互和测试。 Gradio的主要优点是易用性和灵活性。你只需要几行代码就可以为你的模型创建一个交互界面。你…

go的反射和断言

在go中对于一个变量&#xff0c;主要包含两个信息变量类型&#xff08;type&#xff09;和变量值&#xff08;value&#xff09; 可以通过reflect包在运行的时候动态获取变量信息&#xff0c;并能够进行操作 对于Type可以通过reflect.TypeOf()获取到变量的类型信息 reflect.Ty…

python基础实例

下一个更大的数 定义一个Solution类&#xff0c;用于实现next_great方法 class Solution: def next_great(self, nums1, nums2): # 初始化一个空字典answer&#xff0c;用于存储答案 answer {} # 初始化一个空列表stack&#xff0c;用于存储待比较的数字 stack [] # 遍历nu…

Java——面向对象进阶(一)

前言 面向对象进阶(一)&#xff1a;static&#xff0c;继承&#xff0c;this和super关键字 文章目录 一、static1.1 静态变量1.2 静态方法1.3 静态变量和静态方法在内存中 二、继承2.1 概念2.2 继承的特点和能继承什么2.3 继承中的重写2.4 this和super关键字 一、static 在 Jav…

C++ AVL树 详细讲解

目录 一、AVL树的概念 二、AVL树的实现 1.AVL树节点的定义 2.AVL树的插入 3.AVL树的旋转 4.AVL树的验证 三、AVL树的性能 四、完结撒❀ 一、AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但 如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查 …

容器化实践:DevOps环境下的容器交付流程

DevOps的兴起是为了应对市场和消费者对技术应用的不断增长的需求。它的目标是构建一个更快的开发环境&#xff0c;同时保持软件的高质量标准。DevOps还致力于在敏捷开发周期中提升软件的整体品质。这一目标的实现依赖于多种技术、平台和工具的综合运用。 结合容器化技术与DevO…

Xamarin.Android实现通知推送功能(1)

目录 1、背景说明1.1 开发环境1.2 实现效果1.2.1 推送的界面1.2.2 推送的设置1.2.3 推送的功能实现1.2.3.1、Activity的设置【重要】1.2.3.2、代码的实现 2、源码下载3、总结4、参考资料 1、背景说明 在App开发中&#xff0c;通知&#xff08;或消息&#xff09;的推送&#x…

jadx-gui-1.5 反编译工具使用教程 反混淆 Java android 查看签名

JADX&#xff1a;JADX是一个强大的反编译工具&#xff0c;它支持命令行和图形界面操作。除了基本的反编译功能外&#xff0c;JADX还提供了反混淆功能&#xff0c;有助于提高反编译后代码的可读性。 在Android开发和安全分析领域&#xff0c;反编译工具扮演着至关重要的角色。这…

HTML静态网页成品作业(HTML+CSS)—— 金宝贝儿童教育机构介绍网页(2个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有2个页面。 二、作品演示 三、代…

【数据分享】中国高技术产业统计年鉴(2023年)

大家好&#xff01;今天我要向大家介绍一份重要的高技术产业发展情况统计数据资源——《中国高技术产业统计年鉴》。这份年鉴涵盖了从2023年中国高技术产业发展情况的全面数据&#xff0c;并以多格式提供免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 …

离散数学答疑 3

&#xff5e;A&#xff1a;A的补集 有时候空集是元素&#xff0c;有时候就是纯粹的空集 A-B的定义&#xff1a; 笛卡尔积&#xff1a; 求等价关系&#xff1a;先求划分再一一列举 不同划分&#xff1a;分几块。一块&#xff1a;两块&#xff1a;三块&#xff1a;分别计算 Ix是…

LeetCode62不同路径

题目描述 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。问总共有多少条不同的路径&#xff1f; …