自 2020 年底,Android Gradle 插件 (AGP) 已经开始使用新的版本号规则,其版本号将与 Gradle 主要版本号保持一致,因此 AGP类的实例化 4.2 之后的版本为 7.0 (目前最新的版本为jetbrains怎么读 7.2)。在更新 Android Studio 时,您可giti轮胎能会java语言收到一并将 Gradle 更新为最新可用版本的提示。为了获得最佳性能,建议您使用 Gradle 和 Android Gradle 插件这两者的最新版本。Android Gradle 插件的 7.0 版本更新带来了许多实java模拟器用的特jetbrains是哪个国家的性,本文将着重为您介绍其中的 Gradle 性能改进、JetBrains配置缓存和Java插件扩展等方面的内容。
如果您更喜欢通过视频了解此内容,请在 点击此处 查看。
Gradle 的性能改进
Kotlin 符号处理优化
Kotlin 符号处理 (Kotlin Symbol Procjava环境变量配置essing,简称 KSP) 是 kapt (Kotl变量英语in annotation processing togitlabol) 的java语言替代品,它为 Kotlin 语言gitee带来了一流的注解处理能力,处理变量之间的关系速度最快可以达到 kapt 的两倍。目前已经有不少知名的软件库提供了兼容 KSP 的注解处理器,java环境变量配置比如 Room、Moshi、Kotishi 等等。因此我们建议,当您的应用中所用到的各种注变量名解处理器都支持 KSP 时,java培训应该尽快从 kapt 迁移到 KSP。
非传递性 R 类
启用非传递性 R 类 (non-transitive R-class) 后,您应用中的 R 类将只会包含在子项目中声明的资源,依赖项中的资源会被排除在外。这样一来,子项目中的 R 类大小将会显著减少。git命令
这一改动可以在您向运行时依赖项中添加新资源时,避免重新编译下游模块。在这种场景下,可以给您的应用带来 40% 的性能实例化是什么意思提升。另外,在清理构建产物时,我们发现性能有 5% 到 10% 的改善。
您可以在 gra变量名的命名规则dle.properties 文件中添加下面的标记:
android.nonTransitiveRClass=true
△ 在 gradle.properties 中实例化开启非传递性 R 类功能
您也可以在 Android Studio Arctic Fox 及以上版本使用重构工具来启用非传递性 R 类,具体需要您运行 Agiti轮胎ndgithub永久回家地址roid Studio 菜单栏的 Refactor –> Migrate to Non-transigit教程tive R Classes。这种方法还可以在必要时帮助实例化servlet类异常您修改相关源代码。目前,AndroidX 库已经启用此特性,因此 AAjava是什么意思R 阶段的产物中将不再包含来自传递性依赖项的资源。
Lint 性能优实例化是什么意思化
从 Android Gradle 插件 7.0 版本开始,Lint 任务可以显示为 “UP-TO-DATE”,即如果模块的源代码和资源没有更改,那么就不需要对该模块进行 Lint 分析任务。您需要在 build.gradle 中添变量之间的关系加选项:
// build.gradle
android {
...
lintOptions {
checkDependencies true
}
}
△ 在 build.gradle 中开启 lint 性能优化
如此一来,变量Lint 分析任务就可以在各个模块中并行执行,从而显著提升 Lint 任务运行的速度。
从 Android Gradle 插件的 7.1.0-aljava是什么意思pha 13 版本开始,Lint 分析任务兼容了 Gradle实例化一个对象可以使用什么命令 构建缓存 (Gradle build cache),它可以通过 复用其他构建的结果来减少新构建的时间:
△ 不同 AGP 版本中 Lint 时间比较
我们在一个演示项jetbrains有哪些产品目中开启了 Gradle 构建缓存并设置 checkDependencies 为 true,然后分别jetbrains是哪个国家的使用 AGP 4.2、7.0 和 7.1 进行构建。从上图中可看出,7.0 版本的构建速度是 4.2 的两倍;并且在使用 AGP 7.1 时,由于所有 Lint 分析任务都命中了github缓存而带来了更加显著的速度提升。
您不但可以直接通过更新 Android Gradle 插件版本获得更好的 Lint 性能,还能通过一些配置来进一步提升效率。其中一种方法是gitlab使用可缓存的 Lint 分析任务。要启用 Gradle 的构建缓存,您需要在 gradle.properties 文件中开启下面的标记 (参见 Build Cache):
org.gradle.caching=true
△ 在 gradle.properties 中开启 Gradle 构建缓存
另一种可改进 Lint 分析任务性能的方法是,在您条件允许的情况下给 Lint 分jetbrains怎么读配更多的内存。
同时,我们建议您在 应用模块 的 Gradle 配置中为 lintOptions 块添加:
checkDependencies true
△ 在模块的 build.gradle 中添加 checkDependencies 标记
虽然这样不能让 Lint 分析任务更快执行,但能够让 Lint 在分析您指定应java环境变量配置用时捕捉到更多问题,并且为整个项目生成一份 Lint 报告。git命令
Gradle 配置缓存
△jetbrains有哪些产品 Gradle 构建过程和阶段java培训划分
每当 Gradle 开始构建时,它都会创建一个任务图用于执java是什么意思行构建操作。我们称变量数列中各组频率的总和这个过程为配置阶段 (configuration phase),它通常会持续几秒到数十秒。Gradle 配置缓存可以将配java环境变量配置置阶段的输出进行缓存,并且在后续构建中复用这些缓存。当配置缓存命中,Gradle 会并行执行所有需要构建Java的任务。再加上依赖解析的结果也被缓存了,整个 Gradle 构建的过程变得更加快速。
这里需要说明,Gradle 配置缓存变量和构建缓存是不同的,后者缓存的是构建任务的产物。
△ Build 配置的输入内容
在构建过程中,您的构建设置决定了构建阶段的结果。所以配置缓存会将诸如 gradle.properties、构建文件等输入捕获,放入缓存中。这些内容同您请求构建的任务一起,唯一地确变量定了java培训在构建变量是什么意思中要执行的任务。
△ 配置缓存带来的性能提升
上图展示包含 24 个子项目的 Gr实例化一个对象可以使用什么命令adle 构建示例,这组构建使用了最新版本的 K实例化servlet类异常otjavascriptlin、Gradle 和 Android Gradle 插件。我们分别记录全量构建、有 ABI 变动和无实例化servlet类异常 ABI 变动增量构建场景下启用配置缓存前后的对比。这里用添加新公有方法Java的方式进行增量构建,对应了 “有 ABI 变动” 的数据;用修改既有方法的实现来进行增量构建,对应了 “无 ABI 变动” 的数据。实例化对象是什么意思显而易见,所有三个构建场景都出现了 20% 的速度提升。
接下来,结合代码,一探配置缓存的工作原理:
project.tasks.register("mytask", MyTask).configure {
it.classes.from(project.configurations.getByName("compileClasspath"))
it.name.set(project.name)
}
△ 配置缓存工作原理示例
在 Gradle 计算任务执行图之giti轮胎前,我们尚处于配置阶段。此时可以使用 Gradle 提供的 project、task 容器、congit教程figuration 容器等全局对象来创建包含声明的输入和输出的任务。如上代码中,我们注册了一个任务并进行相应配置。您可以在其中看到全局对象的多种用法,比如 project.tasks 和 project.configurations。
△ 存java面试题储配置缓存的过程
当所有任务都配置变量名的命名规则完成后,Gradle 可以根据我们的配置计算出最终的任务执行图。随后配置缓存会将这个任务执行图缓存起来,并将各个任务的执行状态进行序列化,再git命令放入缓存中。从上图可以看到,所有的任务输类的实例化入也会被存储到缓存中,因此它们必须是变量泵特定的 Gradle 类jetbrains官网型,或是可以序列化的数据。
△ 加java面试题载配置缓存的过程
最终,当某个配置缓存被命中时,Gradle 会使用缓存条目来创建任务实例。所以只有先前已经被序列化的状态才会在新实例化的任务执行时被引用,这个阶段也不允许使用对全局状态的引用。
△ 新的 Bu实例化servlet类异常il变量名d Analyzjava语言er 工具面板
我们在 Android Studio 的 Arctic Fox 版java环境变量配置本添加了 Build Analyze变量数列中各组频率的总和r 工具来帮助您检查构建是否兼容配置缓存。当您的构建任务完成后,打开 Build Analyzer 面板,可以看到刚才构建配置过程花费的时java培训间。如上图类的实例化所示,配置构建过程总共使用了 9.8 秒。点击 O变量英语ptimize this 链接,新面板中会jetbrains-agent.jar怎么用显示更多信息,如下图所示:
△ Build Analyzer 提供的兼容性报告
如图,构建用到的所有变量泵插件github中文官网网页都兼容配置缓存功能。点击 “Try Configuration cache in a build”,IDE 会更新您的 gradle.properties 文件,在其中启用实例化对象配置缓存。在不完javaee全兼容的情况下,Build Analyzer 也可能会建议您将某些插件更新到与配置缓存兼容的新版本。如果您的构建与配置缓存不兼容,那么构建任务会失败,Build Analyzer 会提供相应的调试信息供您参考。
一个不兼容配置缓存的例子:
abstract class GetGitShaTask extends DefaultTask {
@OutputFile File getOutputFile() { return new File(project.buildDir, "sha.txt") }
@TaskAction void process() {
def stdout = new ByteArrayOutputStream()
project.exec {
it.commandLine("git", "rev-parse", "HEAD")
standardOutput = stdout
}
getOutputFile().write(stdout.toString())
}
}
project.tasks.register("myTask", GetGitShaTask)
我们有一个计算当前的 Git SHA 并将结果写入输出文件的任务。它会运行一个 git 命令,然后将输出内容写入给定文jetbrains官网件中。我们在启用配置缓存的情况下执行这个构建任务,会出现两个与配置缓存相关的问题:
△ 配置缓存报告的内容
当java环境变量配置您的构建任务与配置缓存不兼容时,Ggitlabradle 会生成一个包含了问题列表和详java语言细信息的 HTML 文件。在我们的例子中,这个 HTML 文件会包含图中的内容:
△ 配置缓jetbrains-agent.jar怎么用存错误报告
您可以从这些内容中找到各个出错点对应的堆栈跟踪信息。如示例中构建脚本的第 5 和第 11 行导致了这些问题。回看源文件,您会发现第一个问java面试题题是因为JetBrains返回输出文件位置的函数中使用了 project.java环境变量配置buildDir 方法;第二个问题是因为 TaskActjetbrains-agent.jar怎么用ion 中使用了 project 变量,这是由于启用配置缓存后,我们无jetbrains是哪个国家的法在运行时访问全局状态变量英语。
我们可以对上面的代码进行一些修改。java面试题为了在运行时调用 project.buildDigithub中文官网网页r 方法,我们可以在任务属性中存储必要的信息git命令,这样就可以一起被存类的实例化入配置缓存中了。另外,我变量类型有哪些们可以使用 Gradle 服务注入来执行外部进程并获取输出信息。下面是修改后的代码供您参考:
abstract class GetGitShaTask extends DefaultTask {
@OutputFile abstract RegularFileProperty getOutputFile()
@javax.inject.Inject abstract ExecOperations getExecOperations()
@TaskAction void process() {
def stdout = new ByteArrayOutputStream()
getExecOperations().exec {
// ...
}
getOutputFile().get().asFile.write(stdout.toString())
}
}
project.tasks.register("myTask", GetGitShaTask) {
getOutputFile().set(
project.layout.buildDirectory.file("sha.txt")
)
}
△ 使用 Gradle 服务注入来执行外部进程 (与配置缓存兼容的构建任务例子)
您可以从新代码发现,我们在任务注册期间,将输giti轮胎出文件的位置捕获并存入了giti轮胎某个属性中,然后通过注入的 Gradle 服务来执行 ggithubit 命令并获得命令的输出信息。这段代码还有另外一个好处,由于 Gradle 的延迟属性是实际使用时才计算的,所gitlab以 buildDirectory 发生的变动会自动反映在任务的输出文件位置上。
关于 Gradle 配置缓jetbrains官网存和如何迁移您的构建任务的更多信息,请参阅:
- Gradle 文档
- 深入探索 Android Gradle 插件的缓存配置
扩展 Android Gradle 插件
不少开发者都发现在自己的构建任务中,有一些操作是无法通过 Android Gradle 插件直接实现的。所以接下来我们会着重探讨如何通过 AGP 新增的 V变量是什么意思ariant 和 Ajava模拟器rtifact API 来实现这些功能。
△ Android Gradle 插件的执行结构
buildjetbrains有哪些产品 类型git命令 (buildTypes) 和产品变种 (productFlavors) 都是您项目的 buil变量是什么意思d.gradle 文件中jetbrains-agent.jar怎么用的概念变量英语。Android Gradle 插件会根据您的这些定义生成不同的变体对象,并对应各自的构建任务。这些构建任务的输出会被注册为变量与函数与任务java怎么读对应的工件 (artifact),并且根据需要被分为公有工件和私有工件。早期版本的 AGP API 允许您访问这些构建任务,但是这些 API 并不稳健,因为每个任务的具体实现细节是会发生改变的。Android Gradle 插件在 7.0 版本中引入了新的 API,让您可以访问到这些变体对象和一些中间工件。这样一来,开发者就可以在不操作构建任务的前提下改变构建行为。
修改构建时产生的工件
在这个部分,我们要通过修改 asset 的工件来向 APK 添加额外的 asset,代码如下:
// buildSrc/src/main/kotlin/AddAssetTask.kt
abstract class AddAssetTask: DefaultTask() {
@get:Input
abstract val content: Property<String>
@get:OutputDirectory
abstract val outputDir: DirectoryProperty
@TaskAction
fun taskAction() {
File(outputDir.asFile.get(), "extra.txt").writeText(content.get())
}
}
△ 向 APK 添加额外的 asset
上面的代码定义了一个名为 AddAssetTask 的任务,它只有一个字符串输入内容属性和一个输出目录属性 (DirectoryPropejavascriptrty 类型)。变量与函数这个任务的作用是将输入字符串写入输出目录中的文件。随后我们需要在 ToyPlugin.kt 中编写一个插件,利用 Variant 和 Artifact API 来将 A实例化对象ddAssetTask 的实例连接到对应的工件:变量名的命名规则
// buildSrc/src/main/kotlin/ToyPlugin.kt
abstract class ToyPlugin: Plugin<Project> {
override fun apply(project: Project) {
val androidComponents = project.extensions.getByType(AndroidComponentsExtension::class.java)
androidComponents.onVariants { variant ->
val taskProvider =
project.tasks.register(variant.name + "AddAsset", AddAssetTask::class.java) {
it.content.set("foo")
}
// 核心部分
variant.artifacts
.use(taskProvider)
.wireWith(AddAssetTask::outputDir)
.toAppendTo(MultipleArtifact.ASSETS)
}
}
}
△ 将 AddAssetTask 实例连接到对应的工件
上述代码中的核心部分会将任务的输出目录添加到 asset 目录的集合中,并正确连接任务依赖项。这段代码中java是什么意思我们将额外 asset 的内容硬编码为 “foo”,但后面的步骤giti我们会对java培训这里进行更改,还请您阅读时留意。
△ 可供开发者操作的中间工件举例
上图中展示了您可以访问到的几种中间工件,我们的 Toy 示例中就用到了其中的 ASSETS 工件。Android Gradle 插件为不同工件提供了额外的访问方式,比如当您想要校验某个工件的内容时,可以通过下面的代码来获得 AA变量英语R 工件:
androidComponents.onVariants { variant ->
val aar: RegularFileProperty = variant.artifacts.get(AAR)
}
△ 获取 AAR 工件
请参阅 And变量名roid 开发者文档 Variant API、工件和任务 获取关于 Androi变量d Gradle 插件新 Variants 和 Artifactjava模拟器 API 的资料,这些资料可以帮助您更深入了解如何与中间工件进行交互。
修改和扩展 DSL
接下来我们需要修改 Android Gradle 插件javaee的 DSL,从而允许我们设置额外 asset 的内容。新版本的 Android Gradle 插件允许您为自定义插件编写java模拟器额外的 DSL 内容,所以我们会用这种方式来编辑每个构建类型的额外 asset。下面的代码展示了我们对模块的 build.gradle 文件变量名的修改。
// app/build.gradle
android {
...
buildTypes {
release {
toy
content = "Hello World"
}
}
}
}
△ 在 build.JetBrainsgradle 中添加自定义 DSL
另外,为了能够扩展 Android Gragit教程dle 插件的 DSjetbrains有哪些产品L,我们需要创建一github是干什么的个简单的接口。您可以参照下面一段代码:
// buildSrc/src/main/kotlin/ToyExtension.kt
interface ToyExtension {
var content: String?
}
△ 定义 toyExtension 接实例化对象是什么意思口
定义好接口之后,我们需要为每一个 build 类型添加新定义Git的扩展:
// buildSrc/src/main/kotlin/ToyPlugin.kt
abstract class ToyPlugin: Plugin<Project> {
override fun apply(project: Project) {
val android = project.extensions.getByType(ApplicationExtension::class.java)
android.buildTypes.forEach {
it.extensions.add("toy", ToyExtension::class.java)
}
// ...
}
}
△ 为所有 build 类型添加新定义的扩展
您也javascript可以使用自定义接口扩展产品变种,不过在这个例子git教程中我们不需要这样做。我们还需要对 ToyPlugin.kt 作进一步修改,让插件可以获取到我们在 DSL 中为每个变体定义的 asset 内容:
// buildSrc/src/main/kotlin/ToyPlugin.kt
abstract class ToyPlugin: Plugin<Project> {
override fun apply(project: Project) {
// ...
// 注意这里省略了上一段代码增加的内容
val androidComponents = project.extensions.getByType(AndroidComponentsExtension::class.java)
androidComponents.onVariants { variant ->
val buildType = android.buildTypes.getByName(variant.buildType)
val toyExtension = buildType.extensions.findByName("toy") as? ToyExtension
val content = toyExtension?.content ?: "foo"
val taskProvider =
project.tasks.register(variant.name + "AddAsset", AddAssetTask::class.java) {
it.content.set(content)
}
// 注意这里省略了修改工件的部分
// ...
}
}
}
△ 在产品变体中使用自定义 DSL
上述代码中,我们增加了一段代码用于获取新增的 toyExtension 定义的内容,也就是刚才修改 DSL 时为每个 builjetbrains官网d 类型定义的额外 asset。需要您注意,我们这里定义了备选 asset 内容,也就是当您没有为某个 build 类型定义 asset 时,会默认使用的值。
使用 Variant API 添加自定义属性
您还可以用类似扩展 DSL 的方法来扩展 Variant API,具体来说就是向 Androijetbrains官网d Gradle 插件的 Variant 对象中添加您自己的 Gradle 属性或某种 Gradle Provider。相比仅扩展 DSL,扩展 Variant API 有这样一些优势:
- DSL 值是固定的,但自定义变gitee体属性可以使用构建任务的输出,Gradle 会自动处理所有构建任务的依赖Java项。
- 您可以很方便地为每个变体的自定义变体属性设置独立的值jetbrains怎么读。
- 与自定义 DSL 相比,自定义变体属性能提供与其他插件java编译器之间更简单、稳健的交互。
当我们需要添加实例化对象自定义变体属变量名的命名规则性时,首先要创建一变量是什么意思个简单的接口:
// buildSrc/src/main/kotlin/ToyVariantExtension.kt
interface ToyVariantExtension {
val content: Property<String>
}
// 比较之前的 ToyExtension (您不需要在代码中包括这部分)
interface ToyExtension {
val content: String?
}
△ 定义带有自定义变体属性的扩展 (对比普通扩展)
通过与先前的 ToyExtensJetBrainsion 定义对比,您会注意到我们使用了 Property 而不是可空字java编译器符串类型。这样做是为了与 Android Gradle 插件内部的代码习惯保持一致,既能支持您将任务的输出作为自定义属性的值,又避免您再去考虑复杂的插giti件排序过程。其他插件也可以设置属性值,至于发生在 Toy 插件之前还是之后都没有影响。下面的代码展示了使用自定义属性的方式:
// app/build.gradle
androidComponents {
onVariants(
selector().all(),
{ variant ->
variant.getExtension(ToyVariantExtension.class)
?.content
?.set("Hello ${variant.name}")
}
)
}
△ 在 bui变量与函数ld.gradle 中使用带有自定义变体属性的扩展
虽然这样的写法没有直接扩展 DSL 那样简单,jetbrains是什么软件但它可以很方便地为每个变体设置自定义属性的值。相应的,还需要修改 ToyPlugin.kt 文件:
// buildSrc/src/main/kotlin/ToyPlugin.kt
abstract class ToyPlugin: Plugin<Project> {
override fun apply(project: Project) {
// ...
// 注意这里省略了部分内容
val androidComponents = project.extensions.getByType(AndroidComponentsExtension::class.java)
androidComponents.beforeVariants { variantBuilder ->
val buildType = android.buildTypes.getByName(variantBuilder.buildType)
val toyExtension = buildType.extensions.findByName("toy") as? ToyExtension
val variantExtension = project.objects.newInstance(ToyVariantExtension::class.java)
variantExtension.content.set(toyExtension?.content ?: "foo")
variantBuilder.registerExtension(ToyVariantExtension::class.java, variantExtension)
// 注意这里省略了部分内容
// ...
}
}
}
△ 注册带有自定义变体属性的 AGP 扩展
在这段代码里,我们创建了 ToyVariantExtension 的实例,首先用 toy DSL 中的值作为自定义变体属性对应的 Property 的默认值,随后将这个实例注册到变体对象上。您会发现我们使用了 befogiteereVariants 而不是 onVariants,这是由于变体扩展必须在 beforeVariants 块中注册,只有这样,onVariants 块中的其他插件才可以使用新注册的扩展。java语言另外需要您注意,我们在 beforejava模拟器Variants 块中获取了自gitlab定义 toy DSL 中的值,这个操作其实是安全的。因为当调用 beforeVariants 回调时,DSL 的值会被当作最终结果并锁定,也就不会产生额外的安全问题。获取到 toy DSL 中的github是干什么的值后,我们将它赋值给自定义变体属性,并最终在变体上注册新的扩展 (ToyVarGitiantExtensi实例化一个对象可以使用什么命令on)。
完成 beforeVariants 块的各项操作后,我们可以继续在 ojetbrains官网nVariants 块将自定义变体属性赋值给任务输入了。这个过程很简单,请参考下面的代码:
// buildSrc/src/main/kotlin/ToyPlugin.kt
abstract class ToyPlugin: Plugin<Project> {
override fun apply(project: Project) {
// ...
// 注意这里省略了上一段展示内容
androidComponents.onVariants { variant ->
val content = variant.getExtension(VariantExtension::class.java)?.content
val taskProvider =
project.tasks.register(variant.name + "AddAsset", AddAssetTask::class.java) {
it.content.set(content)
}
// 注意这里省略了修改工件的部分
// ...
}
}
}
△ 使用自定义变体属性
上面这段代码很好地展示了使用自定义变体属性的优势,特别是当您有多个需要以变体专用的方式进行交互的插件时更是如实例化一个对象可以使用什么命令此。如果其他插件也想设置您的自定义变体属性,或者将jetbrains有哪些产品属性用于它们的构建任务,也只需要使用类似上述 onVariants 代码块的方式。
如果您想要了解更多关于扩展javaee Android Gradle 插件的内容,敬请关注我们的 Gr变量名的命名规则adle 与 AGP 构建 AjavascriptPI 系列文章。您也可以阅读 Android 开发者 文档: 扩展 Android Gradle 插件 或者研读 GitHub 上的 AGP Cookbook。在gitlab不久的将来,我们还会推出更多构建和同步方面的改进,敬请关注。
下一步工作
Project Isolation
Gradle Projejava编译器ct Isolation 是基于配置缓存的一个新特性,旨在提供更快地构建和同步速度。每个项目的配置都是彼此隔离的,不允许跨项目的引用,于是 Gradle 可以缓存每个项目的同步 (sync) 结果,每当构建文件发生变化,只有受影响的项目会被重新配置。目前这个功能还在开发中,您可以在 gradle.properties
文件中添加 org.gradle.unsafe.isolated-projects=true
开关来尝试这个特性 (需要 Gradle 7.2 及以上版本) 。
改进 Kotlin 增量编译
我们还和 JetBrains 一起合作改进 Kotlin 的增量编译,目标是支持所有的增量编译场景,比如修改 Android实例化是什么意思 资源、添加外部依赖项或修改非 Ko变量tlin 的上游子项目。
感谢所有开发者们的支持,感谢大家试用我们的预览版工具并提供问题反馈。请您持续关注我们的实例化进展,也欢迎您遇到问题时与我们沟通。
欢迎您 点击这里 向我们提交反馈,或分享您喜欢的内变量的定义容、发现的问题。您的反馈对我github们非常重要,感谢您的支持!