Android 开发脚本查找项目未使用到的图片

前言

这一年来我一直在研究以脚本作为工具,来辅助平时的需求开发,从而达到最终能减少1/3的敲代码时间,此乃磨刀不误砍柴工。整个过程中也开发了很多个业务相关的脚本,因为是业务相关的,自然不好做分享,而且意义也不大,毕竟大家的业务都大不相同,没太大参考意义。

这里正好其中有个脚本和业务没关系,它虽然简单,但是蕴含了一些算法的思路,所以可以单独拿来分享一下。这个脚本的功能就是:排查项目中未用到的图片资源

脚本实现思路

要排查项目中未用到的图片资源,AS也已经有现成的Lint工具提供给我们使用,那为什么还要单独去写脚本来做这件事,这不是脱裤子放屁吗,我不太想对这件事来做争论,有些东西,你做过,那就是你的,你只去看,它不一定是你的。

回归正题,如果我们要实现这个功能,要怎么做呢?很简单,最暴力的办法就是遍历图片文件夹获取到图片名,然后遍历整个项目的问题,去进行字符串匹配

但是整个项目的文件会很多,所有都遍历会十分耗时,所以可以在这基础上去进行优化,只遍历[.java; .kt;.xml]的文件,或者比如你的项目做模块化比较清晰,有些基础模块是完全不包含资源的,那就可以完全排除去遍历这些模块(这就是和业务相关的方面)

脚本实现

因为脚本和业务相关的比较多,不好去改造成Demo,我这里就贴这个脚本v1.0的代码,现在用的v2.0不太方便展示,不过没关系,核心的思想是一样的。

ini 复制代码
# 查询无用图片
import os

# 指定要遍历的文件夹路径
folder_path1 = 'xxxxxxxxxxxxxxx'  # 这里业务相关,就不显示具体路径了
folder_path2 = 'xxxxxxxxxxxxxxx'  # 这里业务相关,就不显示具体路径了
img_path = 'xxxxxxxxxxxxxxx'      # 这里业务相关,就不显示具体路径了


def get_quer_count(file_name, path):
    # 遍历文件夹内的所有文件t
    result = 0
    for root, dirs, files in os.walk(path):
        for file in files:
            file_path = os.path.join(root, file)
            try:
                with open(file_path, 'r', encoding='utf-8') as f:
                    if "/build/" not in f.name:
                        content = f.read()
                        if file_name in content:
                            result = 1
            except (UnicodeDecodeError, FileNotFoundError):
                # 处理编码错误或文件未找到的情况
                a = 0
    return result


# 开始执行遍历
print("------------  未用到图片有 ---------------------")
for root, dirs, files in os.walk(img_path):
    for file in files:
        parts = file.split('.')
        file_name = parts[0].strip()
        result = get_quer_count(file_name, folder_path1)
        result_count = 0
        if result == 0:
            result_count = result_count + 1
        result2 = get_quer_count(file_name, folder_path2)
        if result2 == 0:
            result_count = result_count + 1
        if result_count == 2:
            print(file_name)

OK,可以看到这用很少的代码就能实现这个效果。

这里有必要再扩展说一下,我用的是python脚本,但并不是只能用py,你也可以用shell,你也可以用php,你也可以用js,甚至你用java也能实现这样的效果。我用py是因为所有脚本语言里面我对py更熟练,而且py的开源库有很多都很牛逼(比如我要实现给一张非矢量图,去查找项目是否存在对应的图片,我可以直接用py的现成库去找相似率90%的图片,这个功能就能快速的开发出来)

其次folder_path、folder_path2是我这里业务相关的只会涉及图片引用的两个模块,其它模块都不涉及图片引用,所以我这里的实现是只遍历这两个模块,并不是说你抄过去也固定这样写。

最后看得出这串脚本很简陋,并没有说像是封装后能给所有人共用的样子,这其实是和环境有关,我这边需求量一直比较多,写脚本基本都是下班时间或者每次写2分钟这种东拼西凑写好的,所以对我来说第一原则是能用就行,而且很多的脚步都是业务相关的,我自然就不打算好好封装提供所有项目使用,所以我的意思是我只是想展示实现的过程,想直接抄去用的话就不太方便了

看看脚本执行后的效果

假设我加入一张没有使用的图片的drawable中

运行py之后

可以看到有打印出来

存在的问题

虽然能实现,但是这个写法还是会存在一些问题:

(1)运行时间的问题

上面使用暴力的方式进行查询,时间复杂是O(m*n)

所以需要尽可能的排除掉没有使用图片的路径,尽可能的缩小范围。

在遍历中,如果找到了存在匹配成功的情况下,可以直接break,没必要再进行后续的遍历。

(2)字符串匹配的问题

上面也说了,这个功能的实现的原理是对所有文件进行字符串匹配。但是就可能会出现图片名是aaa_test,但是代码中有"aaa_test",不是引用的图片,但是字符串匹配上了,也会判断成有引用,挥着存在字符串"xxxaaa_testxxx"这种包含了图片名的字符串,这是会存在误判。

我这边是因为图片的命名都存在前缀,所以基本不会出现这种情况。或者你也可以在判断有字符串匹配之后再进一步判断是否匹配"R.drawable.aaa_test"或"@drawable/aaa_test",还有对getIdentifier()的情况做单独判断。

相关推荐
ERROR_LESS4 分钟前
【ADS-1】【python基础-2】基本语法与数据结构(列表、字典、集合)
python
2401_841495644 分钟前
【数据结构】基于Floyd算法的最短路径求解
java·数据结构·c++·python·算法··floyd
一晌小贪欢10 分钟前
Python爬虫第6课:Selenium自动化浏览器与动态内容抓取
爬虫·python·selenium·网络爬虫·python基础·python3·pathon爬虫
番石榴AI1 小时前
自己动手做一款ChatExcel数据分析系统,智能分析 Excel 数据
人工智能·python·数据挖掘·excel
星期天要睡觉1 小时前
深度学习——循环神经网络(RNN)
人工智能·python·rnn·深度学习·神经网络
消失的旧时光-19431 小时前
ScheduledExecutorService
android·java·开发语言
Blossom.1181 小时前
把AI“撒”进农田:基于极值量化与状态机的1KB边缘灌溉决策树
人工智能·python·深度学习·算法·目标检测·决策树·机器学习
Red Car1 小时前
如何向文件夹内所有PDF增加水印
python·pdf
Q_Q5110082852 小时前
python+uniapp基于微信小程序团购系统
spring boot·python·微信小程序·django·uni-app·node.js·php
小糖学代码2 小时前
MySQL:14.mysql connect
android·数据库·mysql·adb