当前位置: 首页 > article >正文

【Android】组件化嘻嘻嘻gradle耶耶耶

文章目录

  • Gradle基础
  • 总结:
    • gradle-wrapper
    • 项目根目录下的 build.gradle
    • setting.gradle
    • 模块中的 build.gradle
    • local.properties 和 gradle.properties
  • 组件化:
    • 项目下新建一个Gradle文件
      • 定义一个ext扩展区域
        • config.gradle全局基础配置(使用在项目build中,确保属性的引用)
        • config_build.gradle通用配置(使用在各个build里(其实可用也可不用))
      • 在build.gradle中导入config.gradle
    • Base基础层:
      • 建立一个libBase模块
      • 修改libbase的builde.gradle
    • 组件层(业务)
      • 建立一个login组件模块
      • 修改login的builde.gradle
        • 1.引入config_build文件
        • 2.不引入
          • 解释:
    • app层:
      • 修改App的build.gradle

Gradle基础

Gradle 是一种基于 Groovy 的构建工具,被用于 Android 项目的构建、编译和打包。它提供了强大的构建自动化功能,使得在 Android 应用开发中管理依赖、设置环境和自定义构建流程变得更加方便和灵活。

在 Android 开发中,Gradle 被广泛用于构建项目、处理依赖、运行测试、生成 APK 等任务。下面是一些关于 Android 中的 Gradle 的重要说明:

  1. 构建脚本: Android 项目中的 build.gradle 文件是 Gradle 的核心配置文件。它定义了项目的构建设置、依赖关系和任务。通常,一个 Android 项目包含根目录下的 build.gradle 文件和每个模块(如 app 模块)下的 build.gradle 文件。
  2. 插件: Android Gradle 插件是为了与 Android 构建系统集成而设计的 Gradle 插件。在项目的 build.gradle 文件中,通过引入 com.android.application 或 com.android.library 插件,可以使 Gradle 成为适用于 Android 应用或库的构建工具。
  3. 任务: Gradle 使用任务(Task)来定义构建过程中需要执行的操作。常见的任务包括编译代码、打包应用、运行测试、生成 APK 等。Gradle 支持自定义任务,可以根据需要扩展构建过程。
  4. 依赖管理: Gradle 管理 Android 项目的依赖关系。通过 dependencies 块,可以指定项目所需的外部库和模块。Gradle 可以自动从远程 Maven 仓库或本地文件系统下载依赖项,并将其包含到项目的构建路径中。
  5. 变体: Android Gradle 插件引入了变体(Variant)的概念,用于管理不同构建类型(如 Debug 和 Release)和不同产品风味(如不同的应用标识符或资源配置)的构建变体。通过变体,可以针对不同的构建配置生成不同的 APK。
  6. 构建类型和产品风味: Android Gradle 插件允许定义多个构建类型和产品风味,以满足不同的需求。构建类型可以是 Debug、Release 或自定义的构建类型,而产品风味可以设置不同的应用标识符、资源和其他配置。

Gradle在Android项目中有两个比较重要的文件,那就是工程下的build.gradle和模块下的build.gradle,如下图所示:

在这里插入图片描述

当我们将项目结构切换为Android模式时,打开Gradle Scripts,就可以看到排在最前面的是工程的build.gradle,然后是模块的build.gradle,只要看文件括号后面的内容就知道这个build.gradle作用的范围是什么,虽然两者都是build.gradle,但因为作用范围不同,实际的功能就不同。

在这里插入图片描述

① 工程build.gradle

在 Android 工程中,项目的根目录下有一个名为 build.gradle 的文件,通常称为 “工程级 build.gradle”,用于配置整个项目的构建设置。下面是一个简单的 Android 工程级 build.gradle 文件的示例:

// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    id 'com.android.application' version '8.1.3' apply false
    id 'org.jetbrains.kotlin.android' version '1.9.0' apply false
}

上述示例中的 plugins 块配置了插件,并指定插件的版本,这是新版本的工程build.gradle,它将一些功能放到settings.gradle中,下面我们会说到。

② 项目build.gradle

在 Android 项目中,每个模块(如 app 模块、library 模块等)都有一个对应的模块级 build.gradle 文件,用于配置该模块的构建设置和依赖项。下面是一个简单的 Android 模块级 build.gradle 文件的示例:

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}

android {
    namespace 'com.example.hellokotlin' 
    compileSdk 33 // 指定编译使用的 Android SDK 版本

    defaultConfig {
        applicationId "com.example.hellokotlin" // 应用的唯一标识符
        minSdk 24 // 最低支持的 Android 版本
        targetSdk 33 // 目标 Android 版本
        versionCode 1 // 版本号
        versionName "1.0" // 版本名称

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release { 
            minifyEnabled false  // 是否开启代码混淆
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' // 混淆规则文件
        }
    }
    compileOptions {        //编译选项
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {                //Kotlin编译基于Jvm的版本
        jvmTarget = '1.8'
    }
     // 其他配置项,如构建变体、签名配置等
}

dependencies {  // 依赖项

    implementation 'androidx.core:core-ktx:1.9.0'
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.8.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

plugins 声明了所应用的插件,例如 ‘com.android.application’ 表示应用 Android 应用插件,org.jetbrains.kotlin.android表示Kotlin语言插件,如果你使用Java语言开发,则不需要这个插件。

android 块用于配置 Android 构建设置,其中包括编译和构建的相关配置。例如,compileSdkVersion 指定了编译使用的 Android SDK 版本,defaultConfig 定义了默认的配置项,如应用标识符、最低支持版本、目标版本等。

buildTypes 块用于定义不同构建类型(如 release、debug)的配置。通过这个块,可以控制是否开启代码混淆、添加混淆规则等。

dependencies 声明了该模块的依赖项。使用 implementation 关键字可以引入所需的库和模块。例如,androidx.appcompat:appcompat:1.6.1’ 引入了 AndroidX AppCompat 库。

如图中这些则保存在:

在这里插入图片描述

可以在文件的其他部分定义自定义任务和其他配置块。这些可以根据项目需求进行个性化配置,例如添加构建任务、自定义变体等。

需要注意的是,每个模块都有自己的 build.gradle 文件,但具体的配置选项和依赖项可能因模块类型和项目需求而有所不同。建议参考具体模块的 build.gradle 文件和官方文档来了解和调整配置。

③ settings.gradle

settings.gradle 是 Android 项目的根目录下的一个重要文件,它用于配置项目的模块和构建设置。

这里需要说明一下,实际上关于settings.gradle项目在旧版本的Android Studio上没有这么多内容,只是对工程下面的模块进行管理,我们看看之前的settings.gradle中有什么内容,如下所示:

rootProject.name = "FakeQQMusic"
include ':app'

之前的内容比较简单,当你需要改动项目名称或者增加项目中的模块时这个文件才会发生变化。大概是在大黄蜂版本开始发生了变化,将原本属于工程级build.gradle中的一些功能挪到了settings.gradle中,新版本代码如下所示:

下面是一个常见的 Android settings.gradle 文件的示例及其说明:

// pluginManagement用于管理Gradle插件的仓库相关配置
pluginManagement {
    repositories {
        // google仓库配置,用于获取特定的插件
        google {
            content {
                // 通过正则表达式匹配包含以com.android开头的插件组
                includeGroupByRegex("com\\.android.*")
                // 通过正则表达式匹配包含以com.google开头的插件组
                includeGroupByRegex("com\\.google.*")
                // 通过正则表达式匹配包含以androidx开头的插件组
                includeGroupByRegex("androidx.*")
            }
        }
        // 添加Maven中央仓库,可获取众多开源插件和依赖
        mavenCentral()
        // Gradle官方的插件仓库,用于获取Gradle插件
        gradlePluginPortal()
    }
}

// dependencyResolutionManagement用于控制项目如何解析依赖
dependencyResolutionManagement {
    // 设置依赖仓库的模式,FAIL_ON_PROJECT_REPOS表示如果项目级别的仓库配置不符合预期,构建将失败
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        // 使用google仓库获取与Google和Android相关的依赖
        google()
        // 使用Maven中央仓库获取各种开源库依赖
        mavenCentral()
    }
}

// 设置根项目的名称为FakeQQMusic,方便在构建系统等环境中标识项目
rootProject.name = "FakeQQMusic"

// 在多模块项目中,包含名为'app'的子模块,通常是Android项目的主要应用模块,会参与构建过程
include ':app'

我们着重说明一下增加的部分, settings.gradle 文件中的 pluginManagement 和 dependencyResolutionManagement 配置块中的内容。

这些配置块用于配置 Gradle 插件的仓库和依赖项的解析方式。

  1. 在 pluginManagement 配置块中:

    1. repositories 声明了用于解析 Gradle 插件的仓库。示例中的配置包括 google()、mavenCentral() 和 gradlePluginPortal()。通过这些仓库,Gradle 将查找并下载所需的插件。
  2. 在 dependencyResolutionManagement 配置块中:

    1. repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 设置了仓库模式为 RepositoriesMode.FAIL_ON_PROJECT_REPOS。这表示如果项目中存在本地的仓库,则构建过程将失败。该配置用于强制 Gradle 仅使用远程仓库解析依赖项,而不依赖本地仓库。
    2. repositories 声明了用于解析项目依赖项的仓库。示例中的配置包括 google() 和 mavenCentral()。

通过这些仓库,Gradle 将查找并下载项目所需的依赖项。

这些配置块的作用是为 Gradle 构建过程提供正确的插件和依赖项解析环境。配置中的仓库声明可以根据项目的需求进行调整,以确保构建正常进行。

④ gradle.properties

gradle.properties 文件是一个位于根目录下的重要配置文件,用于设置 Gradle 构建系统的全局属性。它可以包含一些常用的配置属性和自定义属性,以影响项目的构建过程。其中让人印象最深刻的莫过于Google将库统一迁移到AndroidX下,当时就需要改一个属性android.useAndroidX=true,现在这已经是一个常驻属性了,之前的V4、V7的库你只会在一些老项目上看到,属于时代的眼泪了,下面我们看看这个gradle.properties中的内容

#  指定用于守护进程的 JVM 参数。
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
#  使用AndroidX
android.useAndroidX=true
#  Kotlin 代码样式:“official 官方”或“obsolete 过时”:
kotlin.code.style=official
//kotlin的
#  启用每个库的 R 类的命名空间,以便其 R 类仅包含库本身中声明的资源,而不包含库依赖项中的资源,从而减小该库的 R 类的大小
android.nonTransitiveRClass=true

项目范围的 Gradle 设置。

IDE(例如 Android Studio)用户:

通过 IDE 配置的 Gradle 设置 将会覆盖

本文件中指定的任何设置。

如需了解有关如何配置构建环境的更多详细信息,请访问

http://www.gradle.org/docs/current/userguide/build_environment.html

指定用于守护进程的 JVM 参数。

该设置对于调整内存设置特别有用。

org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8

这一行表示设置最大堆内存为 2048MB,并将文件编码指定为 UTF-8,这样可以在 Gradle 守护进程运行时按照这个内存分配和编码规则来处理相关任务,有助于避免因内存不足等问题导致的构建错误,同时保证文件读写等操作时编码的一致性。


当进行配置后,Gradle 将以试验性的并行模式运行。

此选项仅应在解耦项目中使用。如需了解更多详细信息,请访问

https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects

org.gradle.parallel=true

这里如果启用了该设置(当前被注释掉了),意味着多个模块或者任务可以并行构建,能够加快整体构建速度,但要确保项目是符合解耦条件的,不然可能会出现一些预料之外的构建问题。


AndroidX 包结构,用于更清晰地表明哪些包是随 Android 操作系统捆绑在一起的,以及哪些包是与你的应用程序的 APK 一起打包的。

https://developer.android.com/topic/libraries/support-library/androidx-rn

android.useAndroidX=true

这一设置启用了 AndroidX,AndroidX 是对之前 Android 支持库的重构和改进,采用了新的包名体系,有助于更好地区分系统相关和应用自身相关的库包,方便进行依赖管理以及适配不同版本的 Android 系统等操作。


启用每个库的 R 类的命名空间,使得其 R 类仅包含在该库自身中声明的资源,而不包含来自该库依赖项的资源,

从而减小该库的 R 类的大小。

android.nonTransitiveRClass=true

这一设置让每个库的资源管理更加独立,避免因为依赖传递导致 R 类中包含过多不必要的资源引用,进而减小了 R 类占用的空间,对于优化 APK 大小等方面有一定帮助,使得资源管理更加清晰和高效。

⑤ gradle-wrapper.properties

在 Android 项目中,gradle-wrapper.properties 文件位于根目录下的 gradle/wrapper 文件夹中,它用于配置 Gradle Wrapper。Gradle Wrapper 是一个与项目一起分发的 Gradle 版本管理工具,它可以确保每个构建都使用指定版本的 Gradle,而无需手动安装或配置 Gradle。

gradle-wrapper.properties 文件包含了一些重要的配置属性,用于指定 Gradle Wrapper 的行为和使用的 Gradle 版本。下面看一个示例:

#Tue Oct 22 17:28:24 CST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

上述示例中的 gradle-wrapper.properties 文件包含了以下重要配置和说明:

  • distributionBase 和 distributionPath 配置了 Gradle Wrapper 下载和缓存 Gradle 发行版本的基本路径。默认情况下,它们指向 GRADLE_USER_HOME,即用户的 Gradle 目录。
  • zipStoreBase 和 zipStorePath 配置了压缩文件的基本路径,Gradle Wrapper 会将下载的 Gradle 发布文件存储在这里。默认情况下,它们也指向 GRADLE_USER_HOME。
  • distributionUrl 指定了要使用的 Gradle 发布版本的 URL。通过指定这个 URL,Gradle Wrapper 会自动下载并使用该版本构建项目。

gradle-wrapper.properties 文件的作用是为项目提供一个指定版本的 Gradle。当你使用 Gradle Wrapper 执行构建时,它会根据该文件中的配置自动下载所需版本的 Gradle。这有助于项目的一致性和可移植性,因为每个开发者都可以使用相同的 Gradle 版本构建项目,无需手动配置。

需要注意的是,如果需要更改 Gradle 版本或其他配置属性,可以在 gradle-wrapper.properties 文件中进行相应的修改。比如我可能Gradle需要升级8.1,那么你在改动之后点击Sync Now进行下载配置,具体的配置方式和详细说明可以参考官方文档。

⑥ local.properties

local.properties 文件是一个位于根目录下的本地配置文件,它用于指定本地开发环境中的一些路径和属性。该文件通常用于定义 SDK 和其他构建工具的位置,以便 Gradle 可以正确定位并使用它们。

以下是一个示例 local.properties 文件的内容及其说明:

## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file should *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=D\:\\jetbrains\\Sdk

//可能会有
//sdk.dir=D\:\\Android\\Sdk
//ndk.dir=D\:\\Android\\Sdk\\ndk\\26.1.10909125

上述示例中的 local.properties 文件包含了以下重要配置和说明:

  • sdk.dir 配置了 Android SDK 的位置。这个配置属性指定了 Android SDK 的根目录路径,Gradle 将使用该路径来查找构建所需的 Android 库和工具。
  • ndk.dir 配置了 Android NDK 的位置。这个配置属性指定了 Android NDK 的根目录路径,Gradle 将使用该路径来支持使用 C/C++ 编写的本地代码。

通过在 local.properties 文件中设置这些属性,Android 开发工具链(如 Android Studio 和 Gradle)可以找到和使用正确的 SDK、NDK 版本,并确保项目的构建过程能够正常进行。

请注意,local.properties 文件通常是在 Android 项目的每个开发者的本地环境中设置。这意味着每个开发者可以根据自己的系统配置和需求来设置这些属性,而不会影响到其他开发者。默认情况下你是不需要配置ndk的路径的,需要根据你的实际开发环境和需求来设置 local.properties 文件中的属性。确保路径和属性值与你的系统配置和目录结构一致。

总结:

gradle-wrapper

gradle-wrapper 简单来说就是对 Gradle 的一层封装。为什么需要再封装一层呢?主要有三点原因:

  1. 确保 版本一致性: 让团队成员都使用项目指定的相同版本进行构建,避免因版本差异导致的构建问题
  2. 方便 项目迁移和共享:当项目需要迁移到其他环境或与他人共享时,不需要担心 Gradle 版本的问题,因为 Wrapper 会处理好版本的适配。
  3. 版本更新管理:项目可以方便地更新 Gradle 版本,只需在 Wrapper 的配置中修改版本号,所有使用 Wrapper 的开发者在下次构建时都会自动获取并使用新的版本。

从上图可以看到,gradle-wrapper 相关的文件有四种,分别是:

  • gradle-wrapper.jar:主要是Gradle的运行逻辑,包含下载Gradle;
  • gradle-wrapper.properties:gradle-wrapper 的配置文件,核心是定义了Gradle版本;
  • gradlew:gradle wrapper的简称,linux下的执行脚本
  • gradlew.bat:windows下的执行脚本

由于这篇文章主要是讲配置文件的,这里就主要看看 gradle-wrapper.properties 的文件:

#Tue Oct 22 17:28:24 CST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

参数介绍如下

  • distributionBase:下载的Gradle的压缩包解压后的主目录;
  • zipStoreBase:同distributionBase,不过是存放zip压缩包的主目录;
  • distributionPath:相对于distributionBase的解压后的Gradle的路径,为wrapper/dists;
  • zipStorePath:同distributionPath,不过是存放zip压缩包的;
  • distributionUrl:Gradle版本的下载地址,所有的版本可以看Gradle Distributions。这里有几种类型,分别为:doc:用户文档;bin:二进制文件;all:包含源码、用户文档、二进制文件等;

项目根目录下的 build.gradle

项目根目录下的 build.gradle的文件内容如下所示:

plugins {
alias(libs.plugins.android.application) apply false
}

plugins 声明的是用来构建应用的插件列表。其中 apply false 表示不将该 plugin 应用于当前项目,一般是在需要使用的模块的 build.gradle 文件中声明使用。

7.0以前,Gradle 可以设置很多通用的配置;现在在 7.0 版本之后,这些配置移动到了 setting.gradle 文件。

setting.gradle

setting.gradle 文件内容如下所示:

// pluginManagement用于管理Gradle插件的仓库相关配置
pluginManagement {
    repositories {
        // google仓库配置,用于获取特定的插件
        google {
            content {
                // 通过正则表达式匹配包含以com.android开头的插件组
                includeGroupByRegex("com\\.android.*")
                // 通过正则表达式匹配包含以com.google开头的插件组
                includeGroupByRegex("com\\.google.*")
                // 通过正则表达式匹配包含以androidx开头的插件组
                includeGroupByRegex("androidx.*")
            }
        }
        // 添加Maven中央仓库,可获取众多开源插件和依赖
        mavenCentral()
        // Gradle官方的插件仓库,用于获取Gradle插件
        gradlePluginPortal()
    }
}

// dependencyResolutionManagement用于控制项目如何解析依赖
dependencyResolutionManagement {
    // 设置依赖仓库的模式,FAIL_ON_PROJECT_REPOS表示如果项目级别的仓库配置不符合预期,构建将失败
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        // 使用google仓库获取与Google和Android相关的依赖
        google()
        // 使用Maven中央仓库获取各种开源库依赖
        mavenCentral()
    }
}

// 设置根项目的名称为FakeQQMusic,方便在构建系统等环境中标识项目
rootProject.name = "FakeQQMusic"

// 在多模块项目中,包含名为'app'的子模块,通常是Android项目的主要应用模块,会参与构建过程
include ':app'

顾名思义,setting.gradle 文件主要存储项目相关的设置信息。比如说可以在 setting.gradle 文件中设置了插件仓库位置、依赖仓库位置这些通用的配置;以及指定项目构建需要依赖哪些模块。

模块中的 build.gradle

plugins {
    // 当前模块应用的插件
    // 使用libs版本目录中定义的android.application插件(通过前面的版本目录配置关联),
    // 通常这个插件用于将当前模块配置为一个可运行的Android应用程序模块
    alias(libs.plugins.android.application)
}

android {
    // android 相关的配置信息,会被引入的 com.android.application 插件使用

    // 定义应用的命名空间,用于在Android系统中唯一标识该应用,类似于包名的作用
    namespace 'com.example.fakeqqmusic'
    // 指定编译项目所使用的SDK版本,这里设置为34,表示使用Android SDK 34进行编译
    compileSdk 34

    defaultConfig {
        // 应用在Android系统中的唯一标识符,等同于早期的包名概念,用于安装、启动等操作
        applicationId "com.example.fakeqqmusic"
        // 定义应用支持的最低Android系统版本,这里设置为28,表示该应用能在Android 28及以上版本运行
        minSdk 28
        // 定义应用的目标Android系统版本,即主要针对该版本进行功能优化和测试,这里是34
        targetSdk 34
        // 应用的版本代码,是一个整数,用于在应用市场等场景区分不同版本,每次发布新版本时通常需要递增
        versionCode 1
        // 应用的版本名称,是一个字符串,通常是方便用户识别的版本号形式,如"1.0",可以按照自己的规则来命名
        versionName "1.0"

        // 指定用于运行Android测试用例的测试运行器,这里使用的是AndroidJUnitRunner,它是Android测试框架中常用的运行器
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            // 是否启用代码压缩和混淆,设置为false表示在生成发布版本(release)时不进行代码压缩和混淆操作。
            // 如果设置为true,则会根据下面指定的proguardFiles进行代码的压缩和混淆处理
            minifyEnabled false
            // 指定Proguard(代码混淆工具)的配置文件,
            // 第一个文件是Android SDK自带的默认优化配置文件,第二个是项目自定义的规则文件,
            // 两者结合起来用于确定具体的代码混淆规则和方式
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    compileOptions {
        // 指定项目源代码兼容的Java版本,这里设置为Java 8版本,意味着可以在项目中使用Java 8的语法特性进行编码
        sourceCompatibility JavaVersion.VERSION_1_8
        // 指定项目编译生成的字节码兼容的Java版本,同样设置为Java 8,确保生成的字节码能在Java 8及以上的运行环境正常运行
        targetCompatibility JavaVersion.VERSION_1_8
    }

    buildFeatures {
        // 启用ViewBinding功能,ViewBinding是一种用于更方便地在代码中访问和操作XML布局文件中视图的机制,
        // 它会为每个XML布局文件生成对应的绑定类,减少了 findViewById 等操作的繁琐性和出错可能
        viewBinding true
        // 启用DataBinding功能,DataBinding允许将数据和布局文件进行绑定,方便实现数据驱动的UI展示,
        // 可以在布局文件中直接使用数据对象和相关表达式,使数据与视图的交互更加简洁直观
        dataBinding true
    }
}

dependencies {
    // 引入appcompat库,这个库提供了对Android早期版本的兼容性支持,比如一些UI组件和功能,
    // 它的版本信息从前面配置的libs.versions.toml文件中通过libs.appcompat获取
    implementation libs.appcompat
    // 引入material库,用于在应用中使用符合Material Design规范的UI组件和样式,
    // 同样其版本是根据libs.versions.toml里的配置通过libs.material获取
    implementation libs.material
}

如上代码所示,模块中的 build.gradle 文件中主要设置了构建需要的信息,这些信息最后会被应用的插件来使用。

local.properties 和 gradle.properties

local.propertiesgradle.properties 文件都是存储配置信息。不同的是,local.properties 设置的是本地的特殊配置,比如sdk的位置;而gradle.properties 设置的是项目相关的配置。

## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file should *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=D\:\\jetbrains\\Sdk
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. For more details, visit
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true

在使用上, local.properties 设置的属性不能直接使用,只能通过文件读取。而 gradle.properties中自定义属性,可以在gradle中可以直接使用。但是对于 xxx.xxx 格式的属性,需要读取文件获取它的属性值,不能直接使用。 local.properties 示例如下:

// 创建Properties对象
        Properties properties = new Properties();

        try {
            // 通过文件输入流加载local.properties文件
            FileInputStream fileInputStream = new FileInputStream(project.getRootProject().getFile("local.properties"));
            properties.load(fileInputStream);

            // 获取sdk.dir属性的值
            String sdkDir = properties.getProperty("sdk.dir");

            // 打印sdk.dir的值
            System.out.println("sdkDir = " + sdkDir);

            // 关闭文件输入流
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

gradle.properties 读取配置示例如下:

//在build.gradle脚本中使用
        String test = "someValue"; // 假设这是从某个地方获取的属性值
        System.out.println("test = " + test);

        // 读取 gradle.properties 文件
        Properties properties = new Properties();
        try {
            properties.load(new FileInputStream("gradle.properties"));
            String androidx = properties.getProperty("android.useAndroidX");
            System.out.println("androidx = " + androidx);
        } catch (IOException e) {
            e.printStackTrace();
        }

组件化:

抽离共用的build.gradle版本数据

我们在APP开发过程中肯定会涉及到不同的手机版本信息,系统信息等等。如果每个模块的信息都是独立的,那么一旦出现版本问题需要修改的情况,将会变得非常麻烦。

这时就需要使用config.gradle统一管理项目的依赖库

项目下新建一个Gradle文件

用于存储项目基本信息,在这里面,我们写上所有依赖库,以及项目中sdk等等的版本号,然后直接让build .gradle去apply它,之后有什么版本的修改升级就可以直接在这里改。

定义一个ext扩展区域

config.gradle全局基础配置(使用在项目build中,确保属性的引用)

用于定义额外的属性和变量,以便在整个构建脚本中共享和重复使用。

//在 Gradle 构建脚本中定义了一些 Android 项目的配置和依赖项版本信息。
ext {

    isDebug = false;    //当为true时代表调试模式,组件可以单独运行。如果是false代表编译打包

    /**
     compileSdkVersion:指定用于编译应用程序的 Android SDK 版本。
     minSdkVersion:指定应用程序可以运行的最低 Android 版本。
     targetSdkVersion:指定应用程序目标的 Android 版本。
     versionCode:用于标识应用程序版本的整数值。
     versionName:用于标识应用程序版本的字符串值。
     */

    android = [
            compileSdkVersion: 33,
            minSdkVersion    : 32,
            targetSdkVersion : 33,
            versionCode      : 1,
            versionName      : "1.0"
    ]

    /**
     * 这是每个模块的application地址
     */
    applicationId = [
            "app"  : "com.example.dome",
            "live" : "com.example.module.live",
            "net"  : "com.example.module.net",
            "login": "com.example.module.login",
            "router": "com.example.module.librouter"
    ]

    //定义了一些常见的 Android 库的依赖项,包括 AppCompat 库、Material Design 库和 ConstraintLayout 库。
    library = [
            "appcompat"       : "androidx.appcompat:appcompat:1.6.1",
            "material"        : "com.google.android.material:material:1.5.0",
            "constraintlayout": "androidx.constraintlayout:constraintlayout:2.1.4"
    ]

    //第三方库单独放置
    libGson = "com.google.code.gson:gson:2.8.6"
    libARouter = "com.alibaba:arouter-api:1.5.2"
    libARouterCompiler = "com.alibaba:arouter-compiler:1.5.2"
}
config_build.gradle通用配置(使用在各个build里(其实可用也可不用))
/**
 * 整个项目(app/module)的通用gradle配置
 * 需要自行确定namespace。需要自行动态判定module是属于application(并配置applicationId),还是library。
 * 默认依赖基础组件module,(:modulesBase:lib_base)
 * 这段注释说明了该配置文件的整体用途,它旨在为整个项目(无论是应用模块还是库模块)提供通用的Gradle配置信息。
 * 同时提到了需要手动处理一些事项,比如确定命名空间以及判断模块类型并相应配置应用标识(针对应用模块),
 * 还指出默认会依赖一个名为'modulesBase:lib_base'的基础组件模块。
 */

// 应用'org.jetbrains.kotlin.android'插件,这表明当前模块是使用Kotlin语言进行Android开发的,
// 该插件会为Kotlin在Android项目中的编译、构建等流程提供相应的支持和配置
apply plugin: 'org.jetbrains.kotlin.android'

android {
    // rootProject 是指项目的根项目,这里从根项目的扩展属性(ext)中获取android.compileSdk的值,
    // 用于指定当前模块编译所使用的Android SDK版本,通过这种方式可以在根项目统一管理所有模块的编译SDK版本
    compileSdk rootProject.ext.android.compileSdk

    defaultConfig {
        // 从根项目的扩展属性(ext)中获取android.minSdk的值,来定义当前模块支持的最低Android系统版本,
        // 确保模块能在该版本及以上的Android设备上正常运行,避免在过低版本系统上出现兼容性问题
        minSdk rootProject.ext.android.minSdk
        // 同样从根项目扩展属性获取android.targetSdk的值,确定模块的目标Android系统版本,
        // 即开发过程中重点针对该版本进行功能优化和测试,保证在该目标版本下功能表现最佳且兼容性良好
        targetSdk rootProject.ext.android.targetSdk
        // 从根项目扩展属性获取android.versionCode的值,作为应用的版本代码,它是一个整数,
        // 用于在应用发布等场景下(例如应用市场)区分不同版本,每次发布新版本时通常需要按照一定规则递增该数值
        versionCode rootProject.ext.android.versionCode
        // 从根项目扩展属性获取android.versionName的值,作为应用的版本名称,它是一个字符串,
        // 一般采用方便用户识别的版本号形式(如"1.0"),开发团队可以按照自己的版本命名规则来设定
        versionName rootProject.ext.android.versionName

        // 指定用于运行Android测试用例的测试运行器,这里使用的是AndroidJUnitRunner,
        // 它是Android测试框架中常用的运行器,便于编写和执行单元测试等各类测试任务
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        javaCompileOptions {
            annotationProcessorOptions {
                // 为注解处理器传递参数,这里将当前项目的名称(通过project.getName()获取)作为参数传递给ARouter模块相关的注解处理器。
                // ARouter是一个用于Android的路由框架,在使用其注解处理器(APT)时,需要传递模块名称这样的参数,
                // 以便在编译阶段正确处理路由相关的注解信息,生成相应的路由映射代码等
                arguments = [AROUTER_MODULE_NAME: project.getName()]
            }
        }
    }

    buildTypes {
        release {
            // 是否启用代码压缩和混淆,设置为false表示在生成发布版本(release)时不进行代码压缩和混淆操作。
            // 如果设置为true,则会根据下面指定的proguardFiles进行代码的压缩和混淆处理,
            // 代码压缩和混淆有助于减小APK大小以及保护代码逻辑不被轻易反编译分析
            minifyEnabled false
            // 指定Proguard(代码混淆工具)的配置文件,
            // 第一个文件是Android SDK自带的默认优化配置文件,第二个是项目自定义的规则文件,
            // 两者结合起来用于确定具体的代码混淆规则和方式,确保在进行代码混淆时按照期望的要求处理代码
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        // 指定项目源代码兼容的Java版本,这里设置为Java 8版本,意味着在项目中可以使用Java 8的语法特性进行编码,
        // 例如Lambda表达式、Stream API等,方便开发者利用更现代的语言特性来编写代码
        sourceCompatibility JavaVersion.VERSION_1_8
        // 指定项目编译生成的字节码兼容的Java版本,同样设置为Java 8,确保生成的字节码能在Java 8及以上的运行环境正常运行,
        // 这保证了编译后的代码可以在符合要求的Java运行时环境中正确执行
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        // 针对Kotlin语言,指定其编译后的字节码所兼容的JVM目标版本为Java 8,
        // 这样在Kotlin代码中可以使用与Java 8兼容的特性以及语法糖等,确保Kotlin代码能在相应的JVM环境下正确运行
        jvmTarget = '1.8'
    }
}

dependencies {
    // 使用implementation不传递依赖,可以防止重复依赖或依赖冲突。
    // 这种依赖方式意味着引入的库只会在当前模块内部使用,不会将该依赖传递给依赖当前模块的其他模块,
    // 有助于控制依赖关系的复杂性,避免不必要的依赖传递导致的问题,例如版本冲突等。
    // 引入项目中名为'modulesBase:lib_base'的模块,这里推测是项目的一个基础组件模块,
    // 可能包含了一些通用的功能、工具类或者资源等,供当前模块使用
    implementation project(':modulesBase:lib_base')
    // ARouter 注解处理器 APT需要在每个使用的组件的build.gradle去添加,并在defaultConfig里添加project.getName。这里属于通用配置,一次配置完。
    // 从根项目扩展属性(ext)中获取arouter_compiler对应的注解处理器依赖,引入该依赖用于处理ARouter框架相关的注解,
    // 在编译阶段通过注解处理器自动生成路由相关的代码,实现页面之间的路由跳转等功能,
    // 这里通过在通用配置中添加,避免在每个使用ARouter的模块中都重复配置该依赖
    annotationProcessor rootProject.ext.arouter_compiler

    // 引入JUnit测试框架,版本为4.13.2,用于在普通测试(test)环境下编写和执行单元测试,
    // 帮助开发者验证模块内各个类和方法的功能正确性
    testImplementation 'junit:junit:4.13.2'
    // 引入JUnit的扩展版本,用于在Android测试(androidTest)环境下执行单元测试,版本为1.1.3,
    // 它提供了一些针对Android平台的测试功能扩展,便于在Android设备或模拟器上进行更贴合实际情况的测试
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    // 引入Espresso测试框架,版本为3.4.0,用于在Android测试(androidTest)环境下编写和执行UI相关的测试用例,
    // 可以方便地对Android应用的用户界面进行功能测试,例如模拟用户点击、输入等操作来验证界面交互的正确性
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

在这里插入图片描述

在业务层中这样引用即可。

引入到主工程、功能层、基础层module

主工程:build.gradle中只需要引入两行代码:

apply plugin: 'com.android.application'
apply from: "${rootProject.rootDir}/config_build.gradle"

功能层,基础层:build.gradle中也只需要引入两行代码:

    apply plugin: 'com.android.library'
    apply from: "${rootProject.rootDir}/config_build.gradle"

注意:注意对比原始配置和抽离出来的通用gradle文件的区别,将特有的自行添加的特定的module。

在build.gradle中导入config.gradle

apply from:"config.gradle

Base基础层:

建立一个libBase模块

修改libbase的builde.gradle

我们创建的library模块会自动设置启动模式为apply plugin: 'com.android.library',这样基础模块就会被打包成一个arr文件,配合其他的业务模块application使用。

// 应用'com.android.library'插件,将当前模块配置为一个Android库模块,
// 意味着这个模块可以被其他Android模块依赖使用,而不是作为一个独立可运行的应用程序
apply plugin: 'com.android.library'

// 简化手写,rootProject.ext的次数,提高性能
// 通过将rootProject.ext赋值给cfg变量,后续可以更方便地访问根项目中定义的扩展属性,避免多次重复书写rootProject.ext,提高代码可读性和编写效率
def cfg = rootProject.ext

android {
    // 命名空间,从根项目扩展属性(cfg)中获取applicationId.net作为当前模块的命名空间。
    // 命名空间用于在Android系统中唯一标识该库模块,类似于包名的作用,方便在不同模块间区分和引用
    namespace cfg.applicationId.net

    // 编译项目所使用的SDK版本,从根项目扩展属性(cfg)的android.compileSdkVersion属性获取具体的版本号,
    // 该属性应该在根项目中提前定义好,这样便于统一管理和修改编译所依赖的SDK版本
    compileSdkVersion cfg.android.compileSdkVersion

    defaultConfig {
        // 定义该库模块支持的最低Android系统版本,从根项目扩展属性(cfg)的android.minSdkVersion属性获取相应数值,
        // 这决定了该库能在哪些版本的Android系统上被使用,避免在过低版本系统上出现兼容性问题
        minSdkVersion cfg.android.minSdkVersion
        // 定义该库模块的目标Android系统版本,即主要针对该版本进行功能优化和测试,从cfg.android.targetSdkVersion获取,
        // 表示开发过程中重点考虑该目标版本下的功能表现和兼容性
        targetSdkVersion cfg.android.targetSdkVersion

        // 指定用于运行Android测试用例的测试运行器,这里使用的是AndroidJUnitRunner,
        // 它是Android测试框架中常用的运行器,方便编写和执行单元测试等测试任务
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            // 是否启用代码压缩和混淆,设置为false表示在生成发布版本(release)时不进行代码压缩和混淆操作。
            // 如果设置为true,则会根据下面指定的proguardFiles进行代码的压缩和混淆处理
            minifyEnabled false
            // 指定Proguard(代码混淆工具)的配置文件,
            // 第一个文件是Android SDK自带的默认优化配置文件,第二个是项目自定义的规则文件,
            // 两者结合起来用于确定具体的代码混淆规则和方式
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    compileOptions {
        // 指定项目源代码兼容的Java版本,这里设置为Java 8版本,意味着可以在项目中使用Java 8的语法特性进行编码
        sourceCompatibility JavaVersion.VERSION_1_8
        // 指定项目编译生成的字节码兼容的Java版本,同样设置为Java 8,确保生成的字节码能在Java 8及以上的运行环境正常运行
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    // 将cfg.library.appcompat对应的库以api依赖的方式引入。使用api依赖意味着该库不仅会在当前模块中使用,
    // 而且当其他模块依赖当前模块时,这个库也会被传递依赖过去,适用于需要暴露给外部模块使用的依赖
    api cfg.library.appcompat
    // 同理,将cfg.library.material对应的库以api依赖的方式引入,方便在模块中使用符合Material Design规范的UI组件和样式等功能,
    // 并可传递给依赖当前模块的其他模块
    api cfg.library.material
    // 将cfg.library.constraintlayout对应的库以api依赖的方式引入,用于布局相关的功能支持,同样可传递给外部依赖模块
    api cfg.library.constraintlayout
    // 将cfg.libGson对应的库以api依赖的方式引入,推测这里的库可能是用于处理JSON数据的Gson库,同样可对外传递依赖
    api cfg.libGson

    // 也可以使用这样的方式一行代码完成:,相当于一个for循环遍历library
    // 下面这行代码会遍历cfg.library中的每个键值对(k表示键,v表示值),并将每个值以implementation依赖的方式引入。
    // implementation依赖表示该库仅在当前模块内部使用,不会传递给依赖当前模块的其他模块
    library.each { k, v -> implementation v }

    // 引入JUnit测试框架,版本为4.13.2,用于编写和执行单元测试,这里是在普通测试(test)环境下使用的依赖
    testImplementation 'junit:junit:4.13.2'
    // 引入JUnit的扩展版本,用于在Android测试(androidTest)环境下执行单元测试,版本为1.1.5,
    // 它提供了一些针对Android平台的测试功能扩展
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    // 引入Espresso测试框架,版本为3.5.1,用于在Android测试(androidTest)环境下编写和执行UI相关的测试用例,
    // 方便对Android应用的用户界面进行功能测试
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

你可以先不管这些什么rootProject.ext.android.minSdk,解释一下,在 Gradle 中,rootProject 是指项目的根项目,即顶层项目。 ext 是 ExtraPropertiesExtension 的缩写,是一个扩展属性的机制。通过将属性添加到 rootProject.ext,你可以在整个 Gradle 构建中共享这些属性。相当于一个全局变量。

组件层(业务)

建立一个login组件模块

这里不介绍了,网上的使用挺多的,依照网上的来就很简单了

修改login的builde.gradle

将涉及到共用部分的写成ext的形式。

1.引入config_build文件
//动态切换集成\组件模式
if (rootProject.ext.isDebug) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}
 
apply from: "${rootProject.rootDir}/config_build.gradle"
 
android {
 
    // 业务组件特定的配置
 
    namespace rootProject.ext.applicationId.main
 
    defaultConfig {
        //组件模式需要applicationId
        if (rootProject.ext.isDebug) {
            applicationId rootProject.ext.applicationId.main
        }
    }
    //动态切换集成/组件模式的AndroidManifest
    sourceSets {
        main {
            if (rootProject.ext.isDebug) {
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/AndroidManifest.xml'
            }
        }
    }
}
 
dependencies {
    // 业务组件特定的依赖配置
 
}
2.不引入
//判断属于打包模式还是调试模式
if (rootProject.ext.isDebug) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}


def cfg = rootProject.ext

android {
    namespace cfg.applicationId.login

    compileSdkVersion cfg.android.compileSdkVersion

    defaultConfig {
        
        //判断如果是调试模式则需要当做一个application启动,则需要一个y
        if (cfg.isDebug) {
            applicationId cfg.applicationId.login
        }

        minSdkVersion cfg.android.minSdkVersion
        targetSdkVersion cfg.android.targetSdkVersion
        versionCode cfg.android.versionCode
        versionName cfg.android.versionName

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    
    //选择合适的manifest
        sourceSets {
        main {
            if (cfg.isDebug) {
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/AndroidManifest.xml'
                    
               //注意我们还需在正式环境下屏蔽Debug包下的所有文件
                java{
                    exclude "**/debug/**"
                }
            }
        }
    }

}

dependencies {

    //导入基础模块
    implementation project(':modulesBase:libBase')

    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
解释:
if (rootProject.ext.isDebug) {
    apply plugin: 'com.android.application'
} else {
    apply plugin: 'com.android.library'
}

这一部分就不解释了哈,从下面解释

在这里插入图片描述

sourceSets 定义了一个 main 源集。

对于 main 源集,使用了一个条件语句(if (cfg.isDebug))来决定使用哪个清单文件。

/debug/”: 这是一个 Ant 风格的通配符。** 表示匹配任意数量的目录,因此 /debug/ 表示匹配任何包含 “debug” 目录的路径。

    sourceSets {
        main {
            if (cfg.isDebug) {
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/AndroidManifest.xml'
                                   //注意我们还需在正式环境下屏蔽Debug包下的所有文件
                java{
                    exclude "**/debug/**"
                }
            }
        }
    }

然后在dependencies中导入了刚才的libBase模块,此时login就具有了libBase所存在的依赖。

implementation project(':modulesBase:libBase')

app层:

修改App的build.gradle

基本和刚才login组件的修改方法相似,plugins不用改动,因为App层不会拿来当作library。

plugins {
    id 'com.android.application'
}

需要注意的就是dependencies。同样的app也需要导入基础模块的依赖,并且app是关联其他的多个组件,这里还需要导入其他组件例如:login

因此在这里也需要判断是否是debug模式,如果是debug模式就不需要导入这些组件。

plugins {
    id 'com.android.application'
}

def cfg = rootProject.ext

android {
    namespace cfg.applicationId.app

    compileSdkVersion cfg.android.compileSdkVersion

    defaultConfig {
        applicationId cfg.applicationId.app

        minSdkVersion cfg.android.minSdkVersion
        targetSdkVersion cfg.android.targetSdkVersion
        versionCode cfg.android.versionCode
        versionName cfg.android.versionName

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
            
                    //让java代码也可以使用isDebug
        buildConfigField("boolean","isDebug",String.valueOf(isDebug))
    }

    //启用buildConfigField功能
    buildFeatures {
        buildConfig true
    }
    
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {

    implementation project(':modulesBase:libBase')
    
    //如果不是Debug的情况下则导入各个组件的模块
    if (!cfg.isDebug){
        implementation project(":modulesCore:live")
        implementation project(":modulesCore:login")
    }

    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

如上即可。

config_build文件的作用其实就是浓缩了一下,简化一点点代码Gradle基础


http://www.kler.cn/a/422145.html

相关文章:

  • python实现c++中so库调用及dbus服务开发
  • 代码随想录第36天
  • pycharm链接neo4j数据库(简单)
  • 【MySql】navicat连接报2013错误
  • 文生视频、图生视频 AI 大模型开源项目介绍【持续更新】
  • ‌UNION和UNION ALL区别
  • 下载 M3U8 格式的视频
  • c++ mfc调用UpdateData(TRUE)时,发生异常
  • ElasticSearch easy-es 聚合函数 group by 混合写法求Top N 词云 分词
  • k8s,声明式API对象理解
  • 基于Java Springboot广西文化传承微信小程序
  • 洛谷 B2029:大象喝水 ← 圆柱体体积
  • 《Vue零基础教程》(5)计算属性和侦听器好讲解
  • 【Linux|计算机网络】HTTPS工作原理与安全机制详解
  • 说说Elasticsearch查询语句如何提升权重?
  • Leetcode 303 Range Sum Query - Immutable
  • 靶机dpwwn-01
  • vue3项目最新eslint9+prettier+husky+stylelint+vscode配置
  • Qt 面试题复习10~12_2024-12-2
  • Android Folding
  • kafka 配置消息编码格式、解决消费者中文乱码
  • uniapp动态表单
  • Llama模型分布式训练(微调)
  • 在RK3588/RK3588s中提升yolov8推理速度
  • WPF_2
  • IOS ARKit进行图像识别