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()的情况做单独判断。

相关推荐
暴力袋鼠哥1 小时前
基于YOLO11的车牌识别分析系统
python
_小马快跑_2 小时前
Android | 利用ItemDecoration绘制RecyclerView分割线
android
_小马快跑_2 小时前
别再手写 if/else 判断了!赶紧来掌握 Kotlin 的 coerce 三兄弟吧
android
_小马快跑_2 小时前
Android Xfermode应用:实现圆角矩形、圆形等图片裁切
android
怀旧,3 小时前
【数据结构】4.单链表实现通讯录
android·服务器·数据结构
yechaoa3 小时前
Widget开发实践指南
android·前端
满怀10153 小时前
【Python进阶】列表:全面解析与实战指南
python·算法
小小菜鸟,可笑可笑4 小时前
Python 注释进阶之Google风格
开发语言·python
upp4 小时前
[bug]langchain agent报错Invalid Format: Missing ‘Action Input:‘ after ‘Action:‘
javascript·python·langchain·bug
小技与小术4 小时前
代码随想录算法训练营day4(链表)
数据结构·python·算法·链表