IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 组件化下如何优雅进行本地调试,即aar依赖与module依赖动态切换 -> 正文阅读

[Java知识库]组件化下如何优雅进行本地调试,即aar依赖与module依赖动态切换

在组件化开发的时候,会面临的一个问题就是组件的调试。

即组件和主工程不在同一个工程目录下,主工程对组件的依赖,是通过依赖组件发布的aar包的方式引入。当组件开发了新的功能,就会发布一个新的 aar 包,并在主工程引入。

但如果这种方式带来的问题就是,如果组件有bug或者需要调试的时候,就会带来不便。具体来说就是,如果改一个问题,就发布一个组件的 aar 包,然后在主工程验证问题是否被修复成功。 这样就会频繁的发布 aar 包,而且调试的效率也低,那有没有办法在开发阶段,直接引用 组件module,而不使用组件的 aar 包呢?答案当然是有的,下面就来介绍一下具体的实现方案。

准备工作:

假设主工程路径:/Users/mei/WorkSpace/AndroidProjects/TestModuleDep

组件工程路径:/Users/mei/WorkSpace/AndroidProjects/module-user/user

组件的maven路径:com.mei.module:user:1.0.0

在主工程的 build.gradle 文件中,引入 user 组件:

dependencies {
    implementation 'com.mei.module:user:1.0.0'
}

一、组件module(源码)依赖方式

从上面的介绍可以知道,主工程 依赖 user 组件,是通过依赖 user 组件的 aar 包的方式进行的。如果想本地调试的话,可以改成依赖组件module 的方式。具体操作如下:

1、include 组件 module

在主工程的 settings.gradle 文件中,把 组件module 加入编译,即 include 组件module。组件跟主工程不在同一个工程目录下,所以,组件module 的 include 方式也有所不同:

include ":user"
project(":user").projectDir = file("/Users/mei/WorkSpace/AndroidProjects/module-user/user")

如上代码所示,在 主工程的 settings.gradle 文件中,增加上述代码,就可以把 组件module 以 include 的方式,加入到主工程中。

2、依赖组件module

在主工程的 app module 中,依赖组件module,即在 app 的 build.gradle 文件中,依赖组件module,同时,把组件的 aar 包依赖给注释掉:

dependencies {
    // implementation 'com.mei.module:user:1.0.0'
    implementation project(':user') // 以 组件module 的方式依赖组件
}

经过上面两步操作,就可以直接依赖组件的源码,而不是组件的 aar 包了,调试起来就非常方便了,不用每次改动都发布一个aar 包。

通过上面的方式,是可以源码依赖的问题,但每次需要调试的时候都这样去改的话,就显得非常的麻烦,还需要把 aar 依赖的方式给注释掉,万一不小心提交了代码,就有可能导致远程无法打包的问题。

那有没有什么方式是在 开发的时候使用 module 依赖,而不改变app 的gradle 文件呢?下面就介绍一种 aar依赖 与 源码依赖快速切换的方式。

二、aar依赖 与 源码依赖 快速切换

在主工程的 build.gradle 文件中,增加如下代码:

allprojects {// 所有组件都添加
    configurations.all {
        resolutionStrategy {
            dependencySubstitution {
            		// module,groupId:artifactId
            		// project,组件module 名称
                substitute module( "com.mei.module:user") with project(':user')
            }
        }
    }
}

上述代码的意思是,以 module 代替 aar 包,则在编译工程的时候,只会把 module 的代码加入编译,而 aar 包的代码不会加入编译。

当然,也可以只在 app 的build.gradle 文件中,加入上述代码,这个时候就可以不用调用 allprojects 方法了,如:

configurations.all {
  resolutionStrategy {
      dependencySubstitution {
          // module,groupId:artifactId
          // project,组件module 名称
          substitute module( "com.mei.module:user") with project(':user') // 注释1 
      }
  }
}

如果不想使用 module 依赖,就可以 把 注释1 的代码,给注释掉,就可以接着使用 aar依赖了。

三、组件依赖封装

经过 二、aar依赖 与 源码依赖 快速切换 的操作之后,我们可以不用 注释掉组件的 aar 依赖,就可以实现 aar依赖 与 module依赖的 快速切换,但还是需要去修改主工程的 settings.gradle 文件和 build.gradle 文件,还是会存在误提交的问题。

如果我把 所有的操作,都放到一个 gradle 文件中,只在主工程的 settings.gradle 文件中,引入这个 gradle 文件,就可以实现上面所有的操作,并且在找不到这个文件的时候,也不会导致编译流程失败,不就可以解决误提交的问题吗?

下面就来看看具体是如何封装的。

1、在 module 工程中,增加 module 依赖文件

在 module 工程中,增加 user_dependency.gradle 文件(完整路径:/Users/mei/WorkSpace/AndroidProjects/module-user/user_dependency.gradle),在这个文件中,实现 组件module 的 引入和 与aar依赖的动态切换功能。注意,这个文件可以不用加入到 git 管理。

1-1、组件module 依赖
include ":user"
project(":user").projectDir = file("/Users/mei/WorkSpace/AndroidProjects/module-user/user")
1-2、aar 依赖 与 组件module 依赖的动态切换

user_dependency.gradle 文件中,增加如下监听:

gradle.addProjectEvaluationListener(new ProjectEvaluationListener() {

    @Override
    void beforeEvaluate(Project projectObj) {
        try {
          	// 增加扩展属性
            if (!projectObj.rootProject.extensions.hasProperty("kotlin_version")) {
                projectObj.rootProject.extensions.add("kotlin_version", "1.4.32")
            }
        } catch (Exception e) {
            e.printStackTrace()
        }
      	// 应用组件工程的全局配置文件
        projectObj.rootProject.apply from: "/Users/mei/WorkSpace/AndroidProjects/module-user/mavenConfig.gradle"

        println "beforeEvaluate project.configurations=${projectObj.configurations}"
    }

    @Override
    void afterEvaluate(Project projectObj, ProjectState state) {
        println "project name is $projectObj"
        println "afterEvaluate project.configurations=${projectObj.configurations}"
        if (projectObj.name != "app") {
            return
        }
      	// 切换 aar依赖 与 组件module 依赖
        projectObj.configurations.all { Configuration ->
            resolutionStrategy {
                dependencySubstitution {
                    substitute module( "com.mei.module:user") with project(':user')
                }
            }
        }
    }
})
  1. 给 gradle 对象,增加 ProjectEvaluationListener 监听事件
  2. 在 ProjectEvaluationListener 的 beforeEvaluate 方法中,增加一些组件需要依赖的额外配置,如果没有,可以不用添加。
  3. 在 ProjectEvaluationListener 的 afterEvaluate 方法中,给指定的工程对象,增加配置信息,如:给 app 工程,增加动态切换 aar依赖 和 module 依赖的 配置。

注意:

  • 要把 afterEvaluate 的 Project 参数重新命名,否则在 dependencySubstitution 闭包中,调用 project() 方法会报错。
  • 只能在 ProjectEvaluationListener 的 afterEvaluate 方法 给工程增加配置信息,因为在 afterEvaluate 方法中,工程的configurations 配置对象不为空,而在 beforeEvaluate 方法中,工程的 configurations 对象是一个空对象,从而也无法 增加配置信息。
1-3、完整的 user_dependency.gradle 代码如下:
// 1. include 组件 module ,注意,使用绝对路径
include ":user"
project(":user").projectDir = file("/Users/mei/WorkSpace/AndroidProjects/module-user/user")

// 2. aar依赖 与 module依赖 动态切换
gradle.addProjectEvaluationListener(new ProjectEvaluationListener() {

    @Override
    void beforeEvaluate(Project projectObj) {
        try {
          	// 增加扩展属性
            if (!projectObj.rootProject.extensions.hasProperty("kotlin_version")) {
                projectObj.rootProject.extensions.add("kotlin_version", "1.4.32")
            }
        } catch (Exception e) {
            e.printStackTrace()
        }
      	// 应用组件工程的全局配置文件
        projectObj.rootProject.apply from: "/Users/mei/WorkSpace/AndroidProjects/module-user/mavenConfig.gradle"

        println "beforeEvaluate project.configurations=${projectObj.configurations}"
    }

    @Override
    void afterEvaluate(Project projectObj, ProjectState state) {
        println "project name is $projectObj"
        println "afterEvaluate project.configurations=${projectObj.configurations}"
        if (projectObj.name != "app") {
            return
        }
      	// 切换 aar依赖 与 组件module 依赖
        projectObj.configurations.all { Configuration ->
            resolutionStrategy {
                dependencySubstitution {
                    substitute module( "com.mei.module:user") with project(':user')
                }
            }
        }
    }
})

2、在主工程的 settings.gradle 文件中,应用依赖文件

在主工程的 settings.gradle 文件中,应用 user_dependency.gradle 文件:

include ":app"

try {
    apply from:"/Users/mei/WorkSpace/AndroidProjects/module-user/user_dependency.gradle"
} catch (Exception e) {
    e.printStackTrace()
}

通过绝对路径的方式,应用 user_dependency.gradle 文件。这里增加 try catch 的目的是,即使找不到 user_dependency.gradle 文件的时候,也不会影响整体的编译流程。即 哪怕引用不到 组件module 还可以使用 aar 依赖。

这样,只需要修改主工程的 settings.gradle 文件,就可以实现 组件 aar依赖 与 组件module 的动态切换,而且 settings.gradle 的修改也可以提交,不会影响线上的的打包流程。

当debug的 时候,如果想用 aar依赖的方式,可以把 应用 user_dependency.gradle 文件的代码注释掉就可以了。
当然,也可以在 user_dependency.gradle 文件中,增加一个 开关,表示是否使用 module 依赖,从而控制 module 与 aar包 的动态切换操作。

如:

.... 

def useModule = true

// 2. aar依赖 与 module依赖 动态切换
gradle.addProjectEvaluationListener(new ProjectEvaluationListener() {

    @Override
    void beforeEvaluate(Project projectObj) {
     	.... 
    }

    @Override
    void afterEvaluate(Project projectObj, ProjectState state) {
        if (projectObj.name != "app") {
            return
        }
      	// 切换 aar依赖 与 组件module 依赖
        projectObj.configurations.all { Configuration ->
            resolutionStrategy {
                dependencySubstitution {
                		if(useModule){ // 只有开关打开的时候,才使用 module 依赖
                				substitute module( "com.mei.module:user") with project(':user')
                		}
                }
            }
        }
    }
})

思考与扩展:

上面的操作,是否可以封装到一个插件中,这样只需要在 主工程中 提供一份 配置信息,就可以动态控制 aar依赖 与 组件module 依赖的动态切换。本地调试也会更加的方便快捷。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-09-07 10:40:45  更:2021-09-07 10:43:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 12:53:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码