开始使用Gradle和Android构建

电脑杂谈  发布时间:2020-05-07 00:02:49  来源:网络整理

gradle 不是内部或外部_gradle 不是内部或外部_内部外部矩阵

无论是否意识到Gradle的存在,每个Android程序员都会直接或间接地处理Gradle. 每当通过Android Studio创建新项目时,AS都会自动创建一个通用目录结构,然后您可以进行开发,在应用程序的build.gradle中添加一些依赖项,单击右上角的立即同步,编写代码,单击绿色小箭头运行代码,一切都很好,只是偶尔“立即同步”将失败并变为“重试”. 如果几次重试后问题仍未解决,请打开浏览器,粘贴相应的错误,找到解决方案,复制并粘贴解决方案gradle 不是内部或外部,单击“重试”,问题就解决了,寿命仍然如此.

如果您想了解问题发生的原因以及解决问题的原因,那么您需要摆脱AS的常见按钮,并探究其背后的秘密-自动构建工具Gradle.

本文将介绍:

为什么需要自动构建工具?默认创建的Android项目具有任何依赖项管理打包过程

通过阅读本文,您可以大致了解Gradle的工作原理,可以有针对性地搜索相关内容,并更快地解决常见的编译错误

以下命令仅是有助于说明问题的示例. 具体用法请参考相关命令手册用法

我们知道APK包实际上是一个包含代码和资源的zip包. 然后我们可以编写一个名为assemble.sh的Shell脚本,任何人都可以通过执行以下脚本来获得apk包,完美:

# 将 .java 文件转换为 .class 文件,执行命令
    
javac xxx.java
    
# Android 还会将 .class 文件转换为 .dex 文件
    
dx xxx.class
    
打包成 apk
    
zip xxx.apk [需要打包的代码和资源]

在Android中,代码通过R.java文件引用资源,因此您需要继续添加命令,并要求在javac命令之前执行此命令. 在实际开发中,我们不可能独自实现所有功能,并且我们可能依赖于出色的开源库. 修改后的伪代码如下:

# 生成 R.java
    
aapt [资源文件]
    
# 将 .java 文件转换为 .class 文件,执行命令
    
javac xxx.java R.java -classpath xxx.jar
    
# Android 还会将 .class 文件转换为 .dex 文件
    
dx xxx.class R.class xxx.jar
    
# 打包成 apk
    
zip xxx.apk [需要打包的代码和资源]

一切似乎都在掌控之中,真的吗?让我们看看Android APK的实际打包过程是什么样的:

实际打包的流程.jpg

考虑实现如此复杂过程的shell脚本是否有点大?不用担心,实施后会遇到以下问题:

这时,我们需要一个简化上述过程的工具. 通过一些约定,例如将代码和资源放在指定目录中,然后补充构建脚本,您可以快速获得最终的构建产品. 这是自动构建工具,Gradle就是其中之一.

与现在的简单示例相比,每个项目都称为Gradle中的Project,而每个需要执行的任务(例如生成R文件和编译Java文件)都称为Gradle中的Task. TaskA.dependsOn(TaskB)可以实现先执行TaskB,然后再执行TaskA的效果. 同时,Gradle还提供了doFirst和doLast,以允许在每个Task之前和之后执行一些代码.

在这一点上,我们知道为什么需要自动化的构建工具:

默认创建的-Android-工程.jpg

无论何时通过Android Studio创建新项目,AS都会自动创建目录结构,如上图所示. 图片简要介绍了每个目录的作用,然后详细介绍了每个目录或文件的含义:

.gradle和.idea存储当前项目的Gradle和AS缓存.

最常见的应用程序之一是,单击“同步”后,AS将在每个项目下生成.iml文件. 它们与.gradle和.idea一起,为我们提供了常见的功能,例如代码提示. 因此,如果您的代码为红色,并且确认依赖性没有问题,则可以尝试以下步骤清除AS缓存:

删除.idea删除.gradle文件并从命令行执行. /gradlewclean选择“文件”->“使缓存无效/ restartSync”

当我们第一次配置Android环境时,我们需要安装Java和AS,但不需要安装Gradle,这是gradle / wrapper的功劳.

在执行gradlew脚本时,可以确保每个项目都使用期望的Gradle版本,而其中的奥秘在于gradlew的代码中

gradle 不是内部或外部_gradle 不是内部或外部_内部外部矩阵

exec"$JAVACMD""${JVM\_OPTS\[@\]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain"$@"

gradlew不会直接启动Gradle,而是启动gradle-wrapper.jar,它将判断是否没有Gradle环境,从gradle-wrapper.properties中的distributionUrl下载相应的环境,然后启动Gradle.

由于Gradle在启动命令行时允许自定义其他参数,因此百度应用程序自定义gradle-wrapper.jar以为具有不同内存大小的计算机实现不同的gradle操作,并通过配置文件Memory调试/发布程序包,从而改善每个人的编译速度.

setting.gradle.jpg

setting.gradle中最重要的是它提供的include方法. 通过这种方法,您可以指定哪些项目需要参与编译. 每个参与Gradle编译的项目都会为其创建一个Project对象

根目录-build.gradle.jpg

首先是buildscript代码块:

gradle默认情况下从上到下执行,无论buildscript代码块在哪里,都将首先执行

接下来是存储库和依赖项:

存储库指示依赖项声明要查找的依赖项的存储库. Google,jcenter和mavenCentral都是第三方Maven存储库. 同时,您还可以通过maven方法添加自己的Maven存储库. 应当注意,不应假定将从特定仓库中提取组件. 如果Gradle请求仓库超时,它将自动请求其他仓库.

依赖关系: 表示Gradle执行所需的依赖关系. 例如,如果您需要Android Gradle插件为我们打包apk包,则需要添加

classpath 'com.android.tools.build:gradle:3.4.0'

最后,所有项目和存储库:

所有项目中的配置将对所有项目均有效,并且其中的存储库指示项目声明要依赖的存储库

app-build.gradle.jpg

首先,您可以看到apply插件: “ com.android.application”. 应用此插件后,它将为我们创建一系列任务,例如assembleDebug,assembleRelease,执行这些任务,您将获得最终的APK.

android代码块是插件提供的API,可让我们修改Task的行为.

依赖项代码块的内容确定当前项目依赖于哪些组件,并且不同的依赖项声明将具有不同的结果. 我们将在下一部分中分析具体内容.

在Android Gradle Plugin 3.0时代,Google使用实现和api选项代替了过去的编译选项. 现在界面已经更改,Google只是简单地重命名了其他配置项,以使每个人都更容易理解其配置的含义. 应当注意,该接口的旧版本不会立即删除,而是会在下一个主要版本中删除. 以下是每个配置项的官方中文说明:

各个配置项的官方中文解释.jpg

例如:

假设A取决于B,B取决于C.

如果B使用对C的实现依赖性,则A无法调用C的代码

gradle 不是内部或外部_内部外部矩阵_gradle 不是内部或外部

如果B对C使用api依赖关系,则A可以调用C的代码

如果B对C使用compileOnly依赖关系,则A无法调用C的代码,并且C的代码也不会打包到APK中

如果B使用runtimeOnlyOnlyOnly仅依赖于C,则A和B无法调用C的代码,但是C的代码将打包到APK中

实际上,每个组件都有其自己的compileClasspath和runtimeClasspath

当组件参与编译时,Gradle会将其放入compileClasspath

当组件参与包装时,Gradle会将其放入runtimeClasspath

实际上,不同的依赖项配置项将声明的依赖项放入不同组件的不同类路径中,并返回到上面的示例

为了实现,实际上是将C放入B的compileClasspath和runtimeClasspath中,并放入A的runtimeClasspath中,以便实现A. 如果调用C的代码,则javac在A的编译阶段会报告一个错误,但最终会报告C将被打包到APK中.

同一原理适用于api,compileOnly和runtimeOnly

当您要依赖源代码项目时,只需这样写

implementation project(':demo:mylibrary')

我们可以清楚地知道,库中的依赖项将被正确打包到APK中

当我们依赖二进制文件时,我们需要这样写

implementation 'androidx.appcompat:appcompat:1.0.2'

执行相关命令时(仅输出发行包的runtimeClasspath)

`./gradlew :app:dependencies --configuration releaseRuntimeClasspath > dependencies.txt`

在输出依赖关系图时,您将看到它不仅依赖于appcompat组件(仅显示某些依赖项),而且还包含该组件自己的依赖项和依赖项依赖项,直到该组件本身具有没有依赖关系. 这种功能称为依赖项传递.

releaseRuntimeClasspath - Resolved configuration for runtime for variant: release
    
\--- androidx.appcompat:appcompat:1.0.2
    
+--- androidx.annotation:annotation:1.0.0
    
+--- androidx.core:core:1.0.1
    
| +--- androidx.annotation:annotation:1.0.0
    
| +--- androidx.collection:collection:1.0.0
    
| | \--- androidx.annotation:annotation:1.0.0
    
| +--- androidx.lifecycle:lifecycle-runtime:2.0.0
    
| | +--- androidx.lifecycle:lifecycle-common:2.0.0
    
| | | \--- androidx.annotation:annotation:1.0.0
    
| | +--- androidx.arch.core:core-common:2.0.0
    
| | | \--- androidx.annotation:annotation:1.0.0
    
| | \--- androidx.annotation:annotation:1.0.0
    
| \--- androidx.versionedparcelable:versionedparcelable:1.0.0
    
| +--- androidx.annotation:annotation:1.0.0
    
| \--- androidx.collection:collection:1.0.0 (*)
    
+--- androidx.collection:collection:1.0.0 (*)
    
+--- androidx.cursoradapter:cursoradapter:1.0.0

那么Gradle如何确定这些依赖关系?使用Maven规范上载组件时,不仅上载组件的二进制文件,还上载pom.xml文件,并且相关性信息也位于该文件中.

由于您可能需要翻墙查看公共Maven服务器,因此下面向您显示了由百度应用程序构建的服务器的背景,以帮助您了解上传的二进制文件如何存储在服务器上


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/ruanjian/article-201115-1.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    • 李林甫
      李林甫

      质检局自己去买来检测的是假货

    • 刘瑞宏
      刘瑞宏

      对于没有加入公约的美国

    • 何幽幽
      何幽幽

      前9个月的CPI是1

    热点图片
    拼命载入中...