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

相关推荐
码海漫游者83 分钟前
让Python成为你的网站引擎:Django全栈开发初体验!!!
数据库·python·其他·django
秋山落叶万岭花开ღ14 分钟前
树的基本概念与操作:构建数据结构的层级世界
数据结构·python·算法
山花35 分钟前
什么是“Pythonic”?——写出更优雅的Python代码(上)
后端·python
用户20187928316735 分钟前
Android 虚拟机的奇妙工厂之旅:从 Dalvik 到 ART 的技术童话
android
用户20187928316741 分钟前
Android 安全机制:应用沙箱与攻防技术的 "快递战"
android
hashiqimiya42 分钟前
android studio底部导航栏
android·ide·android studio
用户2018792831671 小时前
Java 线程池:工厂流水线的高效工人管理
android
用户2018792831671 小时前
Android 耗电统计:城市能源管理的 "电力侦探" 故事
android
ajassi20001 小时前
开源 java android app 开发(十二)封库.aar
android·java·linux·开源
Humbunklung1 小时前
全连接层和卷积层
人工智能·python·深度学习·神经网络·机器学习·cnn