Android加快你的编译速度

工欲善其事,必先利其器。如果每次运行项目都要花费5-10分钟,那人的心态都要崩了。

工欲善其事,必先利其器。如果每次运行项目都要花费5-10分钟,那人的心态都要崩了。

Gradle构建流程

Gradle 的生命周期可以分为大的三个部分:初始化阶段(Initialization Phase),配置阶段(Configuration Phase),执行阶段(Execution Phase)。

优化方案

从整体构建流程可以得知,我们整体上需要从三个方面进行优化:

  • 初始化速度优化

  • 配置速度优化

  • 执行速度优化
    其中执行的过程占比是最大的,所以重心放在执行速度优化上。

1.初始化速度优化

当组件化程度较高时,在开发某个特定功能过程中有些组件是不需要引入的,此时可以在setting.gradle中移除不需要引入的组件模块,可以减少初始化时间

2.配置速度优化

配置阶段主要是对各个build.gradle进行解析,因此可以注意以下几点:

按需引入模块,减少build.gradle的解析
build.gradle中尽量少做耗时操作,例如读取系统时间动态配置apk的名称组成
在开发阶段不是必要执行的任务,可以写判断避免这些任务的配置,例如一些字节码插桩,性能监控之类的。

  • 开启Configuration Cache

在任务执行阶段,Gradle提供了多种方式实现Task的缓存与重用(如up-to-date检测,增量编译,build-cache等)。

除了任务执行阶段,任务配置阶段有时也比较耗时,目前AGP也支持了配置阶段缓存Configuration Cache,它可以缓存配置阶段的结果,当脚本没有发生改变时可以重用之前的结果。

在越大的项目中配置阶段缓存的收益越大,module比较多的项目可能每次执行都要先配置20到30秒,尤其是增量编译时,配置的耗时可能都跟执行的耗时差不多了,而这正是configuration-cache的用武之地。

目前Configuration-cache还是实验特性,如果你想要开启的话可以在gradle.properties中添加以下代码:

# configuration cacheorg.gradle.unsafe.configuration-cache=trueorg.gradle.unsafe.configuration-cache-problems=warn
3.执行速度优化
  • 开启并行编译

开启后会并行执行多个任务,大幅度减少编译时间,只需要在gradle.properties中添加:

org.gradle.parallel=true
  • 增大编译内存

由于大家的电脑配置都不一样,因此具体设置多大内存需要根据个人情况进行合理配置,一般在gradle.properties里已经有相关配置,可以对该配置进行修改,例如

org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

同时在主工程模块的build.gradle中进行修改:

    dexOptions {
        javaMaxHeapSize "4g"
    }
  • 开启按需构建

对没有更改的模块不再进行编译,非常适合已经组件化的项目,在gradle.properties中添加:

org.gradle.configureondemand=true
  • 开启构建缓存

直接使用之前生成的缓存,不再进行构建,在构建时任务后面会显示FROM CACHE,在gradle.properties中添加:

org.gradle.caching=true
  • 开启增量注解编译

支持注解增量编译,不会重新触发编译(gradle高版本中需要移除),在gradle.properties中添加:

android.enableSeparateAnnotationProcessing=true
4.其他速度优化
  • 对AS进行配置

开启离线模式
开启离线模式后不会再开始的时候去检测依赖是否有更新,也不会去下载相关更新的依赖,首次构建不能开启,否则无法完成构建,后续构建可以开启,在某些情况下将大幅度改善编译速度,强烈推荐开发阶段使用。点击下图中的图标的按钮即可开启离线模式,有些版本显示为类似wifi的图标,再次点击取消离线模式:

  • 更改AS内存大小

点击AS的Help菜单项,选中Change Memory Settings选项。

  • KAPT 迁移到 KSP

注解处理器是Android开发中一种常用的技术,很多常用的框架比如ButterKnife,ARouter,Glide中都使用到了注解处理器相关技术。

但是如果项目比较大的话,会很容易发现KAPT是拖慢编译速度的常见原因,这也是谷歌推出KSP取代KAPT的原因。

  • 关闭R文件传递

在 apk 打包的过程中,module 中的 R 文件采用对依赖库的R进行累计叠加的方式生成。如果我们的 app 架构如下:

编译打包时每个模块生成的R文件如下:

1. R_lib1 = R_lib1;
2. R_lib2 = R_lib2;
3. R_lib3 = R_lib3;
4. R_biz1 = R_lib1 + R_lib2 + R_lib3 + R_biz1(biz1本身的R)
5. R_biz2 = R_lib2 + R_lib3 + R_biz2(biz2本身的R)
6. R_app = R_lib1 + R_lib2 + R_lib3 + R_biz1 + R_biz2 + R_app(app本身R)

1.关闭R文件传递可以通过编译避免的方式获得更快的编译速度
2.关闭R文件传递有助于确保每个模块的R类仅包含对其自身资源的引用,避免无意中引用其他模块资源,明确模块边界。
3.关闭R文件传递也可以减少很大一部分包体积与dex数量

从 Android Studio Bumblebee 开始,新项目的非传递 R 类默认处于开启状态。即gradle.properties文件中都开启了如下标记

android.nonTransitiveRClass=true
  • 开启Kotlin跨模块增量编译

使用组件化多模块开发的同学都有经验,当我们修改底层模块(比如util模块)时,所有依赖于这个模块的上层模块都需要重新编译,Kotlin的增量编译在这种情况往往是不生效的,这种时候的编译往往非常耗时。

在Kotlin 1.7.0中,Kotlin编译器对于跨模块增量编译也做了支持,并且与Gradle构建缓存兼容,对编译避免的支持也得到了改进。这些改进减少了模块和文件重新编译的次数,让整体编译更加迅速。

在 gradle.properties 文件中设置以下选项即可使用新方式进行增量编译:

kotlin.incremental.useClasspathSnapshot=true // 开启跨模块增量编译kotlin.build.report.output=file // 可选,启用构建报告
  • Module源码转aar

随着业务量的增大,module的引入也会增多,每个module在编译的时候都需要花费一定的时间。把module转化成aar后就不再需要每次都进行编译或者取缓存,可以减少一部分时间。

来源: 互联网
本文观点不代表码客-全球程序员交流社区立场,不承担法律责任,文章及观点也不构成任何投资意见。

赞 ()

相关推荐

  • 置顶 开发项目接单群,免费入群了

    无论你是Android、ios、java、php,或者你是产品经理、老板,都可以免费入群接单或者发布项目,全程不收取任何费用。

    2025年02月21日 15点27分
  • 鸿蒙Next-AttributeModifier结合@Styles和@Extend深度解析使用

    声明式语法引入了@Styles和@Extend两个装饰器,可以解决复用相同自定义样式的问题,但是存在以下受限场景:

    2025年03月03日 15点40分
  • ConstraintLayout之layout_constraintDimensionRatio属性详解

    layout_constraintDimensionRatio 是 ConstraintLayout 提供的一个强大功能,它可以让 View 按照固定的宽高比例自适应尺寸。使用这个属性,可以在 ConstraintLayout 中根据已知的宽度或高度,自动计算另一个维度,确保 View 保持特定的宽高比。

    2025年03月03日 15点39分
  • Android事件分发时,你浓眉大眼的onTouch()竟然没有执行?

    在开发需求时,有这么一个场景:Activity中有一个ViewGroup作为Parent,ViewGroup里面又有一个Webview作为Child。当一进入页面时,系统输入法自动弹起,而在点击Parent区域时,需要收起系统输入法。背景介绍完毕,当时的第一想法就是通过Parent设置setOnTouchListener,然后在onTouch()回调中来实现:

    2025年03月02日 15点10分
  • Android SDK封装与发布实战指南

    Android SDK封装与发布实战指南

    2025年03月02日 15点05分
  • 鸿蒙Next开发-添加水印以及点击穿透设置

    在鸿蒙Next中,为App全局添加水印可以通过以下方式实现,其中通过窗口添加水印是一种常见且高效的方式。以下是具体方案和实现细节:

    2025年02月26日 23点15分
  • 鸿蒙Next开发-普通函数和箭头函数 this指向的区别以及对UI刷新的影响

    鸿蒙Next开发-普通函数和箭头函数 this指向的区别以及对UI刷新的影响

    2025年02月26日 23点14分
  • 深入探索ArkUI @Builder与@BuilderParam的进阶应用

    在ArkUI的组件化开发体系中,@Builder和@BuilderParam这对装饰器组合扮演着UI模块化的重要角色。二者的差异与配合体现了声明式UI的核心思想:

    2025年02月26日 23点12分
  • Deepseek推荐:Android 开发者需要掌握的系统知识大纲

    一、操作系统基础1. Linux 内核机制内容介绍 Android 基于 Linux 内核,核心机制包括进程管理、内存管理、文件系统、Binder 驱动等。

    2025年02月26日 23点09分
  • Android App 厂商角标适配

    本篇介绍一下笔者在维护IM应用时,设置App角标的相关经验。同时这里设置角标都是基于系统厂商的Launcher,没有适配三方的Launcher应用,因为我们统计下来发现近些年使用三方Launcher应用比较少了,大部分用户还是以系统Launcher为主。所在在我们的项目中,主要是适配各个厂商。

    2025年02月26日 23点07分
  • 鸿蒙Next-方法装饰器以及防抖方法注解实现

    以下是关于 鸿蒙Next(HarmonyOS NEXT)中 MethodDecorator 的详细介绍及使用指南,结合了多个技术来源的实践总结:

    2025年02月26日 22点58分
  • DevEco Studio常用快捷键以及如何跟AndroidStudio的保持同步

    DevEco Studio是华为推出的用于开发HarmonyOS应用的集成开发环境,它提供了丰富的快捷键以提高开发效率,以下为你详细介绍不同操作场景下的常用快捷键:

    2025年02月26日 22点56分
  • Android | 利用ItemDecoration绘制RecyclerView分割线

    RecyclerView.ItemDecoration 是 Android 提供的一种扩展机制,用于为 RecyclerView 的每个子项(Item)添加装饰(Decoration)。它通常用于绘制分割线、边距、背景等,目的是增强 RecyclerView 的显示效果。

    2025年02月26日 22点52分
  • Android 布局优化:利用 ViewStub 和 Merge 提升性能

    提升界面渲染性能是一个至关重要的任务,尤其是在应用启动时,渲染界面需要快速且流畅。为了优化 UI 渲染速度,Android 提供了许多工具,其中 ViewStub 和 Merge 标签是非常有效的布局优化手段。通过合理使用这两者,可以延迟加载不必要的视图、减少布局的嵌套层级,从而加速应用的启动和运行。

    2025年02月26日 22点47分
  • 玩转 ImageView.ScaleType:图片的缩放与裁剪技巧

    ImageView 是最常用的控件之一,它用于展示各种类型的图片。为了能够根据需求调整图片的显示效果,Android 提供了 ImageView.ScaleType 枚举,它可以灵活地控制图片如何适应 ImageView 的尺寸。本文将探讨 ImageView.ScaleType 的不同选项、使用场景及其实现技巧。

    2025年02月26日 22点45分
  • Android加快你的编译速度

    工欲善其事,必先利其器。如果每次运行项目都要花费5-10分钟,那人的心态都要崩了。

    2025年02月25日 15点40分

发表回复

评论列表

点击查看更多

    联系我们

    在线咨询: QQ交谈

    微信:dxmcpjl

    邮件:1529097251#qq.com

    工作时间:周一至周五,9:30-18:30,节假日休息

    微信