Android Gradle依赖汇总

news/2024/5/20 4:03:32 标签: gradle, android, android studio

依赖配置

目前 Gradle 版本支持的依赖配置有(Android Studio 3.0及以上版本,Gradle Version在4.1及以上版本,Android Plugin Version在 3.0及以上版本。):implementation、api、compileOnly、runtimeOnly 和 annotationProcessor。

已经废弃的配置有:compile、provided、apk、providedCompile。

各配置项具体作用如下[括号后面为对应的已废弃的配置]:

  • implementation (compile):会添加依赖到编译路径,并且会将依赖打包到输出(aar或apk),但是在编译时不会将依赖的实现暴露给其他module,也就是只有在运行时其他module才能访问这个依赖中的实现。使用这个配置,可以显著提升构建时间,因为它可以减少重新编译的module的数量。建议,尽量使用这个依赖配置。

  • api (compile):与 compile功能完全一样,会添加依赖到编译路径,并且会将依赖打包到输出(aar 或a pk)。与 implementation 不同,这个依赖可以传递,其他 module 无论在编译时和运行时都可以访问这个依赖的实现,也就是会泄漏一些不应该不使用的实现。举个例子,A 依赖 B,B 依赖 C,如果都是使用 api 配置的话,A 可以直接使用 C 中的类(编译时和运行时)。而如果是使用 implementation 配置的话,在编译时,A 无法访问 C 中的类。

  • compileOnly (provided):Gradle 把依赖加到编译路径,编译时使用,不会打包到输出(aar 或 apk)。这可以减少输出的体积,在只在编译时需要,在运行时可选的情况,很有用。

  • runtimeOnly (apk):只在生成apk的时候参与打包,编译时不会参与,很少用。

  • annotationProcessor (compile):用于注解处理器的依赖配置。

依赖类型

本地源码依赖

dependencies {
    // 【1、本地源码依赖】Dependency on a local library module
    implementation project(":mylibrary")
}

本地libs目录jar包依赖

dependencies {
   // 【2、本地libs目录jar包等依赖】Dependency on local binaries
    implementation fileTree(dir: 'libs', include: ['*.jar'])
}

远程Maven仓库等依赖

dependencies {
    // 【3、远程Maven仓库等依赖】Dependency on a remote binary
    implementation 'com.example.android:app-magic:12.3'
}

依赖加@aar与不加@aar的区别

library可以通过多种格式上传到远程仓库,比如大部分情况下用到的.jar或.aar。当没有指定@后缀的话,依赖的时候将会下载它的默认格式(由上传方定义,如果没有定义则默认为.jar)的Library库。如果指定了@后缀,那么默认看不到它下面的依赖树,为了保证所有的依赖树可以下载下来,即看到此模块下面的依赖树,那么需要这样来定义:

compile ('com.android.support:appcompat-v7:22.1.1@aar') {
    transitive = true
}

而如果没有指定@后缀,那么所有的依赖树均可以下载下来,即:

compile ('com.android.support:appcompat-v7:22.1.1')

排除依赖透传

dependencies中单个依赖排除:

compile('com.hongri.android:accs-huawei:1.1.2@aar') {
        //默认值为false
        transitive = true
        exclude group: 'com.taobao.android', module: 'accs_sdk_taobao'
}

全局配置排除:

configurations {
    compile.exclude module: 'cglib'
    //全局排除原有的tnet jar包与so包分离的配置,统一使用aar包中的内容
    all*.exclude group: 'com.taobao.android', module: 'tnet-jni'
    all*.exclude group: 'com.taobao.android', module: 'tnet-so'
}

禁止依赖传递:

compile('com.hongri.android:foundation:1.0') {
    transitive = false
}
 
configurations.all {
    transitive = false
}

单个依赖项中使用 @jar 标识符忽略传递依赖:

compile 'com.hongri.android:foundation:1.0.0@jar'

依赖树查看

在Terminal 终端输入以下命令,即可看到项目的依赖关系解析树:

./gradlew app:dependencies

我们可以在上面的命令中添加一个标识来查看特定构建变体的配置。例如:

./gradlew app:dependencies --configuration releaseCompileClasspath

这将向我们展示 release 变体的依赖树。

./gradlew app:dependencies --configuration compile //输出模块中compile相关的依赖
./gradlew app:dependencies --configutation compileOnly //输出模块中compileOnly相关的依赖
./gradlew app:dependencies --configutation androidTestCompile //输出模块中androidTestCompile 相关的依赖
releaseCompileClasspath - Resolved configuration for compilation for variant: release
+--- com.android.databinding:library:1.3.1
|    +--- com.android.support:support-v4:21.0.3
|    |    \--- com.android.support:support-annotations:21.0.3 -> 27.0.2
|    \--- com.android.databinding:baseLibrary:2.3.0-dev -> 3.0.1
+--- com.android.databinding:baseLibrary:3.0.1
+--- com.android.databinding:adapters:1.3.1
|    +--- com.android.databinding:library:1.3 -> 1.3.1 (*)
|    \--- com.android.databinding:baseLibrary:2.3.0-dev -> 3.0.1
+--- com.android.support.constraint:constraint-layout:1.0.2
|    \--- com.android.support.constraint:constraint-layout-solver:1.0.2
\--- com.android.support:appcompat-v7:27.0.2
     +--- com.android.support:support-annotations:27.0.2
     +--- com.android.support:support-core-utils:27.0.2
     |    +--- com.android.support:support-annotations:27.0.2
     |    \--- com.android.support:support-compat:27.0.2
     |         +--- com.android.support:support-annotations:27.0.2
     |         \--- android.arch.lifecycle:runtime:1.0.3
     |              +--- android.arch.lifecycle:common:1.0.3
     |              \--- android.arch.core:common:1.0.0
     +--- com.android.support:support-fragment:27.0.2
     |    +--- com.android.support:support-compat:27.0.2 (*)
     |    +--- com.android.support:support-core-ui:27.0.2
     |    |    +--- com.android.support:support-annotations:27.0.2
     |    |    \--- com.android.support:support-compat:27.0.2 (*)
     |    +--- com.android.support:support-core-utils:27.0.2 (*)
     |    \--- com.android.support:support-annotations:27.0.2
     +--- com.android.support:support-vector-drawable:27.0.2
     |    +--- com.android.support:support-annotations:27.0.2
     |    \--- com.android.support:support-compat:27.0.2 (*)
     \--- com.android.support:animated-vector-drawable:27.0.2
          +--- com.android.support:support-vector-drawable:27.0.2 (*)
          \--- com.android.support:support-core-ui:27.0.2 (*)

在查找目的之前,理解 Gradle 依赖关系树的格式很重要。

先来谈谈以下三个符号,它们的目的仅用于格式化:

  • +- - - 是依赖分支库的开始。
  • | 标识还是在之前的依赖库中的依赖,显示它依赖的库。
  • \- - - 是依赖库的末尾。

星号(*) 在依赖库的末尾,意味着该库的进一步依赖关系不会显示,因为它们已经列在其他某个子依赖树中。

最重要的标识是 ->

如果 Gradle 发现多个依赖库都依赖到同一个库但是不同版本,那么它必须做出选择。毕竟包含同一个库的不同版本是没有意义的。在这种情况下,Gradle 默认选择该库的最新版本。例如:

| + — — com.android.support:support-v4:21.0.3
| | \ — — com.android.support:support-annotations:21.0.3 -> 27.0.2

强制指定依赖

  • 在dependencies中配置之后呢,一般情况下高的版本会覆盖旧的低的版本:

    implementation 'com.android.support:appcompat-v7:27.0.2'
    
  • 如果我们想一直使用某个固定版本,那么可以使用如下的强制依赖实现:

    compile('com.hongri.android:foundation:1.0.0') {
        force = true
    }
    
    //或者进行全局配置
    configurations.all {
        resolutionStrategy {
            force 'com.hongri.android:foundation:1.0.0'
            //或这种写法
            forcedModules = ['com.hongri.android:foundation:1.0.0']
        }
    }
    

定义解析策略

dependencySubstitution:

dependencySubstitution接收一系列替换规则,允许你通过substitute函数为项目中的依赖替换为你希望的依赖项:

// add dependency substitution rules
dependencySubstitution {
   //将该module所有的远程依赖替换成源码依赖
   substitute module('org.gradle:api') with project(':api')
   //将该module所有源码依赖替换成远程依赖
   substitute project(':util') with module('org.gradle:util:3.0')
}

eachDependency:

eachDependency允许你在gradle解析配置时为每个依赖项添加一个替换规则,DependencyResolveDetails类型的参数可以让你获取一个requested和使用useVersion()、useTarget()两个函数指定依赖版本和目标依赖。request中存放了依赖项的groupid、module name以及version,你可以通过这些值来筛选你想要替换的依赖项,再通过useVersion或useTarget指定你想要的依赖。

  • 将group是com.android.support且name不等于multidex的所有module版本指定为28.0.2:

    configurations.all {
        resolutionStrategy.eachDependency { DependencyResolveDetails details ->
            def requested = details.requested
            if (requested.group == 'com.android.support') {
                if (!requested.name.startsWith("multidex")) {
                    details.useVersion '28.0.2'
                }
            }
        }
    }
    
  • 将所有module为rxjava的依赖,全都指定使用如下版本:‘io.reactivex.rxjava3:rxjava:3.0.0-RC1’:

    configurations.all {
        resolutionStrategy.eachDependency { DependencyResolveDetails details ->
            if (details.requested.name == 'rxjava') {
                //由于useVersion只能指定版本号,不适用于group不同的情况
                details.useTarget group: 'io.reactivex.rxjava3', name: 'rxjava', version: '3.0.0-RC1'
            }
        }
    }
    

sourceSets应用:

Java插件引入了一个概念叫做SourceSets,通过修改SourceSets中的属性,可以指定哪些源文件(或文件夹下的源文件)要被编译,哪些源文件要被排除。Gradle就是通过它实现Java项目的布局定义。

android {
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
            jniLibs.srcDirs = ['libs']
        }
}
  • 我们可以在sourceSets中配置指定so文件夹:

so文件的默认加载路径是在: src/main/jniLibs, 如果想自定义加载路径,如src/main/libs,那么可以设置:

    sourceSets.main {
        jni.srcDirs = []//disable automatic ndk-build call
        //一般设置libs文件夹路径就行,但某些情况下需要设置全局路径才能找到so文件。所以这里设置的全局路径
        jniLibs.srcDirs = ['src/main/libs']
    }
  • 我们可以在sourceSets中配置指定的Manifest文件:
    sourceSets {
        main {
            if (isDebug.toBoolean()) {
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            } else {
                manifest.srcFile 'src/main/release/AndroidManifest.xml'
            }
        }
    }
  • 如果我想要加一些我需要的java文件,但我们还不想按照java标准的文件夹结构:
sourceSets {
    main {
        java {
            srcDir 'src/myJavaPath'
        }
    }
}
  • 如果我想在打包的时候, 不包含某些文件, 可以如下进行设置:

        sourceSets {
            main {
                java {
                    exclude '/test/**'  // 不想包含文件的路径
                }
                resources {
                    exclude '/resource/**' // 不想包含的资源文件路径
                }
                .....
            }
        }
    

声明主DEX中必需的类:

在构建多DEX时, 编译工具会执行复杂的决策来确定主DEX文件中需要的类,以便能够成功启动。如果主DEX文件中没有提供启动时需要的任何类,就会奔溃出现java.lang.NoClassDefFoundError错误。对于代码依赖复杂或者自检机制,就可能不会将这些类识别为主DEX文件中必需类。需要使用multiDexKeepFile 或者 multiDexKeepProguard 声明主DEX文件中必需的类,在构建时如果匹配到就添加到主DEX文件中。

multiDexKeepFile

创建一个名为multidex-config.txt文件,在文件中添加需要放在主DEX的类,每行包含一个类,格式如下:

com/example/MyClass.class
com/example/MyOtherClass.class

然后,您可以按以下方式针对构建类型声明该文件:

android {
   buildTypes {
      release {
         multiDexKeepFile file('multidex-config.txt')
      }
   }
}

注意:Gradle 会读取相对于 build.gradle 文件的路径,因此如果 multidex-config.txt 与 build.gradle 文件在同一目录中,以上示例将有效。

multiDexKeepProguard

multiDexKeepProguard 文件使用与 Proguard 相同的格式,并且支持整个 Proguard 语法。在multiDexKeepProguard 中指定的文件应该在任何有效的 ProGuard 语法中包含 -keep 选项,创建multidex-config.pro文件如下:

  -keep class com.example.MyClass
  -keep class com.example.MyClassToo
  #或者指定包中所有的类
  -keep class com.example.** { *; } // All classes in the com.example package

然后,可以按以下方式针对构建类型声明该文件:

android {
    buildTypes {
        release {
            multiDexKeepProguard('multidex-config.pro')
            ...
        }
    }
}

同样需要注意文件路径问题。


http://www.niftyadmin.cn/n/860891.html

相关文章

检查数组中的数字是否连续,你还有其他方案?

简述 给定一个未排序的数字数组,编写一个函数,如果该数组包含连续的数字,则该函数返回true。 a)如果array为{5,2,3,1,4},则该函数应返回true,因为该数组具有…

python字符串常用操作

# 长度len ss "Python " print("%s len %d" % (ss, len(ss))) # 位置输出 index print("%s p 的位置 %d" % (ss, ss.index("yt"))) # 数量统计 count print("%s 包含 p的个数 %d" % (ss, ss.count("p"))) # 截…

Android中获取唯一的id

文章目录Android唯一设备ID现状IMEIMAC地址唯一Id实现方案那些硬件适合硬件标识工具类Android唯一设备ID现状 设备ID,简单来说就是一串符号(或者数字),映射现实中硬件设备。如果这些符号和设备是—— 对应的,可称之为…

安卓Handler机制重要知识点汇总(必知必会)

在没有Looper的线程&#xff0c;创建Handler会报RuntimeException异常&#xff0c;源码如下&#xff1a; public Handler(Callback callback, boolean async) {if (FIND_POTENTIAL_LEAKS) {final Class<? extends Handler> klass getClass();if ((klass.isAnonymousCla…

快速生成数据库ER图的方式

dbdiagram 简述 快速简单的数据库模型设计工具&#xff0c;可以帮助您使用其自己的特定于域的语言&#xff08;DSL&#xff09;来绘制数据库图。最主要的是免费。 dbdiagram 地址 https://dbdiagram.io/ dbdiagram 效果 Draw.io 简介 对于基于Web的使用免费&#xff0c;对…

ams启动过程以及App的启动过程

本代码基于android sdk 28 Ams启动过程 Ams是有SystemServer启动的&#xff0c;同时SystemServer启动的还有&#xff0c;pms&#xff0c;wms等 //com/android/server/SystemServer.java private void run() {try {traceBeginAndSlog("InitBeforeStartServices");/…

Apache druid Roll-up前后的数据量对比sql,见证roll-up的强大

简述 Roll-up 是Apahce druid 中重要的特性之一&#xff0c;在特定时间段内的数据&#xff0c;维度一致时可以进行压缩合并。减少数据量。 但有时为了估算压缩前后数据量如何查询呢&#xff1f; 在druid 中默认提供了sum函数可以统计压缩前的数据量。 下面来看下语法如何写吧。…

IntentService的使用以及源码解析

简介 IntentService主要用来异步处理耗时的工作&#xff0c;客户端通过调用startService(Intent)调用服务&#xff0c;使用工作线程依次处理每个 Intent&#xff0c;并在工作结束时自行停止&#xff0c;IntentService是抽象类&#xff0c;如果使用&#xff0c;则需要继承Inten…