使用本地和远程的Gradle构建缓存加快构建速度

汇总:Android小白成长之路_知识体系汇总【持续更新中…】

Gradle构建缓存

在使用gradle构建的时候,gradle会对输出进行缓存,便于下一次构建时重用相同的输出,避免重复构建,可以节省大量的时间,对编译速度优化方面具有非常大的帮助,而且gradle新版本中也在逐步地完善缓存,提高命中率,因此使用缓存是非常有必要的优化手段,目前在Android Studio中可以使用本地缓存和远程缓存两种方式,接下来简单介绍一下最基本的配置,了解更多请点击附录中的链接查阅

启用构建缓存

默认情况下,未启用构建缓存,我们需要在gradle.properties中开启缓存,添加字段

org.gradle.caching = true

也可以在命令行进行构建的时候添加--build-cache,例如

./gradlew build --build-cache

配置本地构建缓存

开启构建缓存后,默认开启了本地缓存,而本地缓存默认存储于gradle用户主目录中,但是可以根据需要进行手动配置。打开setting.gradle文件,添加

buildCache{
	local{
		directory = new File(rootDir, 'build-cache')
		removeUnusedEntriesAfterDays = 30
	}
}

其中directory设置的是目录,removeUnusedEntriesAfterDays是多长时间后清除未使用的缓存

配置远程构建缓存

远程构建缓存应用于多人开发的场景,特别是使用了CI构建的场景,因为CI构建足够稳定,可以用作共享缓存,而本地机器则使用CI构建生成的缓存,就能避免一些问题,这些问题后续讲述。先了解如何配置远程构建缓存,同样的,打开setting.gradle文件,添加

buildCache{
	remote(HttpBuildCache){
		url = 'http://example.com/cache'
	}
}

url是缓存的远程后端地址,会在下文中介绍如何简单地配置一个可用的cache后端

配置远程缓存后端

配置缓存后端最简单的方法是使用gradle为我们提供的构建缓存结点gradle/build-cache-node,此结点可以和Gradle Enterprise配合使用,达到最佳效果,但Gradle Enterprise是收费的,这里只单独使用gradle/build-cache-node

使用jar直接启动结点

  • 首先下载build-cache-node的jar包,下载地址:build-cache-node下载

  • 配置java运行环境,不会配置的直接百度搜索即可,这里不做描述。需要注意,9.0以上的版本需要使用java 11及以上的java环境

  • 下载文件后,运行终端,直接进入它所在的文件夹,执行命令:

    java -jar build-cache-node-9.11.jar start
    

    其中版本号需要替换成你下载的版本

  • 上面的启动方式的配置都是默认的,端口号是5071,访问节点主页就是localhost:5071,而在gradle中配置远程缓存的url就是http://localhost:5071/cache

  • 推荐使用的启动方式:

    java -jar build-cache-node-9.11.jar start --data-dir build-cache-node --port 80 --path my-path
    
    • –data-dir:配置缓存的存储文件夹路径
    • –port:配置端口号
    • –path:配置访问的名称,例如上面的配置,在gradle中的url配置应为http://localhost/my-path/cache
  • 节点未提供开机启动的功能,因此我们需要手动去配置开机自动运行上述的命令行,具体方法根据不同的系统而不同,感兴趣的可以去搜素如何开机自动执行

使用docker启动

使用docker启动节点可以更方便管理,同时不需要手动去下载jar包,也能配置开机自动执行

  • 首先安装dockerWindowsmacOS推荐下载Docker DesktopWindows系统需要开启虚拟化技术,因为Windows安装docker需要用到virtual box

  • 在终端运行命令行启动镜像:

    docker run --detach \
        --user $UID \
        --volume build-cache-node:/data \
        --publish 80:5071 \
        --restart always \
        gradle/build-cache-node:9.11 \
        start
        --path my-path
    
    • –user:指定使用的用户,未指定时默认使用root身份,此用户可以读取和写入文件系统,例如data缓存目录,一把直接使用$UID指定为当前登录的用户
    • –volume:指定存储路径,上述的配置指定为当前目录下的build-cache-node文件夹
    • –publish:指定端口,当前指定为80
    • –restart always :配置自动重启策略,always则为始终保持自动重启
    • gradle/build-cache-node:9.11:配置下载的缓存节点的版本,可以使用固定的版本号,也可以使用latest代替,表明使用最新版本,配置这个版本会直接去下载对应的版本,然后才去启动
    • –path:指定访问路径名称,官方说新版本可以配置,不过我这里配置显示–path命令不存在,暂时不知道原因

gradle最佳配置

  • 不使用CI时,gradle可以配置如下:

    buildCache{
    	local{
    		enable = true
    		removeUnusedEntriesAfterDays = 30
    	}
    	remote(HttpBuildCache){
    		url = 'http://example.com/cache'
    		enable = true
    		push = true
    	}
    }
    

    该配置下同时使用本地缓存和远程缓存,构建时会首先检测本地缓存,没有时才会使用远程缓存,push = true当前缓存会上传到远程缓存中,在没有使用CI构建的情况下只能每个人本地上传,但这会导致缓存经常改变,导致其他人命中率没那么高。可以定个规范,主导者创建分支后执行首次编译并且打开开关上传纯净的缓存,其他人关闭这个字段,不上传自己的缓存,只使用远程缓存。

  • 使用CI时,就更加规范了,由于CI构建会保持最新并稳定的已合入代码的缓存,因此可以使用CI的缓存作为远程缓存,本地机器都不进行缓存的上传,gradle配置如下:

    boolean isCiServer = System.getenv().containsKey("CI")
    
    buildCache {
    	local{
    		enable = !isCiServer
    	}
        remote(HttpBuildCache) {
            url = 'https://example.com/cache/'
            push = isCiServer
        }
    }
    

    也就是判断当前环境是否是CI构建环境,如果是的话则关闭本地缓存,开启远程缓存推送,关闭本地缓存是为了保持缓存的纯净度。其他人的本地机器则由于不是CI环境,就不会上传缓存,只会使用远程缓存

其他问题

  • 上面都是用localhost本地地址访问,可以根据实际情况改为正确的地址。例如需要局域网内访问,就应该改为ip地址或者映射后的域名,外网访问则需要配置相关的外网地址
  • 直接在浏览器可以打开localhost:5071,可以在里面配置缓存大小或者访问用户控制,也可以看到缓存占用情况,还可以配置Gralde Enterprise相关信息
  • 直接浏览器打开localhost:5071/cache会遭到访问拒绝,返回一个错误页面,但可以在gradle配置中正常访问
  • 如果不使用CI构建,本地第一位同学首次构建需要上传缓存,所以可能构建时间比不使用远程构建时稍微长一点,但其他人首次构建将大幅度缩减构建时间
  • 如果构建的时候显示类似remote read time out的信息,则需要排查网络,例如局域网的话需要查看是否在同一个局域网下,还需要排查是否挂了VPN导致访问不上。还有一个由于Android Studio导致的非常坑的问题,如果曾经在AS中配置了代理,记得在设置里去掉代理,同时一定要去全局的gradle.properties里查看是否有代理的配置写在里面,因为即使你在设置里不使用代理,这个文件里的代理配置字段也不一定会被清空,很多AS的网络问题都是因为这个引起的!!!
  • 更多配置相关问题请前往附录中的链接地址中查阅

附录

洛谷P1928 外星密码是一道经典的字符串处理题,题目大致描述是这样的:给定一段由外星人发出的信号序列(即一串字母组成的字符串),需要从中找出最长的一个连续子串满足某些特定条件——比如每个字母出现次数均为偶数次或者其他指定规则下的统计特性。 以下是用C语言解决这个问题的基本思路及步骤: ### 解决方案概述 #### 第一步:输入数据 首先读入代表“外星密码”的整个字符串。通常我们会限制这个字符串长度不超过一定值(如题目设定的最大限制)。例如可以用下面的方法来进行存储: ```c char str[MAX_LEN]; // MAX_LEN 应设置得足够大以容纳最大可能的输入大小+1 (用于'\0') scanf("%s", str); // 直接利用scanf读取完整的单词型字符串 ``` #### 第二步:遍历寻找符合条件子串 我们采用双层循环的方式依次检查每一个可能的起始位置i以及结束位置j所形成的子串是否符合要求。对于每次选定的[i,j]区间内的部分,都需要计数其中各个字符的数量,并验证这些数字是否全部为偶数或其他预设的标准。 ```c for(int i = 0; i < strlen(str); ++i){ int count[ALPHA_SIZE]={0}; // ALPHA_SIZE一般设成26适应小写字母表情况 for(int j=i ; j<strlen(str) && valid<=bestValid; j++){ updateCount(count,str[j]); if(checkCondition(count)){ recordBestResult(i,j,...); } } } ``` 这里的伪代码展示了两重嵌套迭代框架结构,内侧随着索引推进不断调整局部频率直方图(`count`)同时测试目标属性达成状况;一旦发现更优结果则保存下来直到最终确定全局最佳解法为止。 #### 实现细节补充说明 - `updateCount`: 增量更新当前考虑范围内某个字符对应的频度计量项数值; - `checkCondition`: 根据实际问题需求定义判断依据函数检验目前收集到的信息集合能否构成合格候选答案; - `recordBestResult`: 当前找到新的较理想匹配区域时记录相关信息供后续比较参考之需。 完整版解决方案可以根据具体约束进一步优化时间复杂度或空间利用率等方面的表现特征。 ---
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nbin_Newby

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值