草庐IT

Android - 统一依赖管理(config.gradle)

leo2777 2023-09-23 原文
Android-GoogleIOSpotlightPrivacyAndSecurity_1024x512.png

前言

本文属于 《一款基于MVP架构的快速应用开发框架,kotlin版本》(注:此文章还在更新中,可先看看,敬请期待!) 的扩展文章,详细介绍在使用 LeoFastDevMvpKotlin 快速开发框架的时候,进行项目依赖管理的方法。

介绍

Android 依赖统一管理距目前为止,博主一共知道有三种方法,分别是:

  1. 传统apply from的方式(也是本文想讲的一种方式):新建一个 「config.gradle」 文件,然后将项目中所有依赖写在里面,更新只需修改 「config.gradle」 文件内容,作用于所有module。
  2. buildSrc 方式:当运行 Gradle 时会检查项目中是否存在一个名为 buildSrc 的目录。然后 Gradle 会自动编译并测试这段代码,并将其放入构建脚本的类路径中, 对于多项目构建,只能有一个 buildSrc 目录,该目录必须位于根项目目录中, buildSrc 是 Gradle 项目根目录下的一个目录。
  3. Composing builds 方式:复合构建只是包含其他构建的构建. 在许多方面,复合构建类似于 Gradle 多项目构建,不同之处在于,它包括完整的 builds ,而不是包含单个 projects,总的来说,他有 buildSrc 方式的优点,同时更新不需要重新构建整个项目。

三种方式各有各的好,目前最完美的应该是第三种实现。但是这种方式不利于框架使用,因为它属于的是新建一个module,如果项目远程依赖了框架,默认也包含了这个 module。所以博主选择了第一种方式。以下文章也是围绕第一种方式进行讲解。

实现方式

实现这个统一依赖管理,拢共分三步,分别是:

  • 第一步:创建「config.gradle」 文件
  • 第二步:项目当中引入「config.gradle」
  • 第三步:在所有module的「build.gradle」当中添加依赖
  • 第一步:创建 「config.gradle」 文件

    首先将 Aandroid Studio 目录的Android格式修改为Project,然后再创建一个「config.gradle」的文件

    1681962514751.jpg

    然后我们编辑文章里面的内容,这里直接给出框架的代码出来(篇幅太长,省略部分代码):

    ext {
    /**
     * 基础配置 对应 build.gradle 当中 android 括号里面的值
     */
    android = [
            compileSdk               : 32,
            minSdk                   : 21,
            targetSdk                : 32,
            versionCode              : 1,
            versionName              : "1.0.0",
            testInstrumentationRunner: "androidx.test.runner.AndroidJUnitRunner",
            consumerProguardFiles    : "consumer-rules.pro"
            
            ......
    ]
    
    /**
     * 版本号 包含每一个依赖的版本号,仅仅作用于下面的 dependencies
     */
    version = [
            coreKtx              : "1.7.0",
            appcompat            : "1.6.1",
            material             : "1.8.0",
            constraintLayout     : "2.1.3",
            navigationFragmentKtx: "2.3.5",
            navigationUiKtx      : "2.3.5",
            junit                : "4.13.2",
            testJunit            : "1.1.5",
            espresso             : "3.4.0",
            
            ......
    ]
    
    /**
     * 项目依赖 可根据项目增加删除,但是可不删除本文件里的,在 build.gradle 不写依赖即可
     * 因为MVP框架默认依赖的也在次文件中,建议只添加,不要删除
     */
    dependencies = [
    
            coreKtx                    : "androidx.core:core-ktx:$version.coreKtx",
            appcompat                  : "androidx.appcompat:appcompat:$version.appcompat",
            material                   : "com.google.android.material:material:$version.material",
            constraintLayout           : "androidx.constraintlayout:constraintlayout:$version.constraintLayout",
            navigationFragmentKtx      : "androidx.navigation:navigation-fragment-ktx:$version.navigationFragmentKtx",
            navigationUiKtx            : "androidx.navigation:navigation-ui-ktx:$version.navigationUiKtx",
            junit                      : "junit:junit:$version.junit",
            testJunit                  : "androidx.test.ext:junit:$version.testJunit",
            espresso                   : "androidx.test.espresso:espresso-core:$version.espresso",
            
            ......
            ]
    }
    

    简单理解就是将所有的依赖,分成版本号以及依赖名两个数组的方式保存,所有都在这个文件统一管管理。用 ext 包裹三个数组:第一个是「build.gradle」Android 里面的,第二个是版本号,第三个是依赖的名字。依赖名字数组里面的依赖版本号通过 $ 关键字指代 version 数组里面的版本号

  • 第二步:项目当中引入 「config.gradle」

    将「config.gradle」文件引入项目当中,在项目的根目录的「build.gradle」文件(也就是刚刚新建的 「config.gradle」同目录下的),添加如下代码:

      apply from:"config.gradle"
    

    需要注意的的是,如果你是 AndroidStudio 4.0+ 那么你将看到这样的「build.gradle」文件

      // Top-level build file where you can add configuration options common to all sub-projects/modules.
      plugins {
          id 'com.android.application' version '7.2.2' apply false
          id 'com.android.library' version '7.2.2' apply false
          id 'org.jetbrains.kotlin.android' version '1.7.10' apply false
      }
      
      apply from:"config.gradle"
    

    相反,如果你是 AndroidStudio 4.0- 那么你将会看到这样的「build.gradle」文件

      
      apply from: "config.gradle"
      
      buildscript {
          ext.kotlin_version="1.7.10"
          repositories {
              maven { url "https://jitpack.io" }
              mavenCentral()
              google()
          }
          dependencies {
          classpath "com.android.tools.build:gradle:4.2.1"
          classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3'
          classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    
          // NOTE: Do not place your application dependencies here; they belong
          // in the individual module build.gradle files
          }
      }
      
      allprojects {
          repositories {
              maven { url "https://jitpack.io" }
              mavenCentral()
              google()
          }
      }
      
      task clean(type: Delete) {
          delete rootProject.buildDir
      }
      
    

    不过仅仅是两个文件里面的内容不一致,这个文件的位置是一样的,而且我们添加的引入代码也是一样的。可以说,这只是顺带提一嘴,实际上不影响我们实现统一依赖管理这个方式。

  • 第三步:在所有module的「build.gradle」当中添加依赖

    这一步是最重要的,我们完成了上面两步之后,只是做好了准备,现在我们需要将我们每一个module里面「build.gradle」文件里面的依赖指向「config.gradle」文件。也就是下图圈起来的 那两个「build.gradle」文件。

    Snipaste_2023-04-20_14-15-58.png

    因为我们第二步的时候已经在根目录引入了「config.gradle」,所以我们在「build.gradle」就可以指向「config.gradle」例如:

          implementation rootProject.ext.dependencies.coreKtx
    

    这一行,就指代了我们「config.gradle」文件里面的 dependencies 数组里面的 coreKtx 的内容。完整示例如下:

      plugins {
          id 'com.android.application'
          id 'org.jetbrains.kotlin.android'
      }
      android {
          namespace 'leo.dev.mvp.kt'
      //    compileSdk 32
          compileSdk rootProject.ext.android.compileSdk
    
          defaultConfig {
              applicationId "leo.dev.mvp.kt"
      //        minSdk 21
      //        targetSdk 32
      //        versionCode 1
      //        versionName "1.0"
      //
      //        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    
              minSdk rootProject.ext.android.minSdk
              targetSdk rootProject.ext.android.targetSdk
              versionCode rootProject.ext.android.versionCode
              versionName rootProject.ext.android.versionName
    
              testInstrumentationRunner rootProject.ext.android.testInstrumentationRunner
    
          }
          
          ......
      }
      
      dependencies {
    
          implementation fileTree(include: ['*.jar'], dir: 'libs')
          
      //    implementation 'androidx.core:core-ktx:1.7.0'
      //    implementation 'androidx.appcompat:appcompat:1.6.1'
      //    implementation
      //
      //    testImplementation 'junit:junit:4.13.2'
      //    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
      //    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
    
          implementation rootProject.ext.dependencies.coreKtx
          implementation rootProject.ext.dependencies.appcompat
          implementation rootProject.ext.dependencies.material
    
          testImplementation rootProject.ext.dependencies.junit
          androidTestImplementation rootProject.ext.dependencies.testJunit
          androidTestImplementation rootProject.ext.dependencies.espresso
          
      }
      
    

    需要注意的是,我们在编写代码的时候,是没有代码自动补全的。所以得小心翼翼,必须要和「config.gradle」文件里面的名字向一致。

注意事项

  • 首先就是这种方式在coding的时候,是没有代码补全的(只有输入过的,才会有提示),我们需要确保我们的名字一致
  • 我们在增加依赖的时候,在「config.gradle」里面添加完之后,记得在对应的module里面的「build.gradle」里面添加对应的指向代码。

总结

以上就是本篇文章的全部内容,总结起来其实步骤不多,也就三步。但是需要注意的是细节。需要保持写入的依赖与「config.gradle」文件一致,并且未写过的词,是不会有代码自动补全的。

另外本篇文章是本文属于 《一款基于MVP架构的快速应用开发框架,kotlin版本》 的扩展文章,所以会一步一步说得比较详细一点。大家可以挑重点跳过阅读。

文末图片.png

有关Android - 统一依赖管理(config.gradle)的更多相关文章

  1. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  4. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  5. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  6. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  7. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  8. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  9. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  10. ruby - (Ruby || Python) 窗口管理器 - 2

    我想用这两种语言中的任何一种(最好是ruby​​)制作一个窗口管理器。老实说,除了我需要加载某种X模块外,我不知道从哪里开始。因此,如果有人有线索,如果您能指出正确的方向,那就太好了。谢谢 最佳答案 XCB,X的下一代API使用XML格式定义X协议(protocol),并使用脚本生成特定语言绑定(bind)。它在概念上与SWIG类似,只是它描述的不是CAPI,而是X协议(protocol)。目前,C和Python存在绑定(bind)。理论上,Ruby端口只是编写一个从XML协议(protocol)定义语言到Ruby的翻译器的问题。生

随机推荐