如何有效的清除Android中无用的资源(静态代码分析)

谁能告诉我怎么设置首图

最近公司要做这个,简单调研了一下,现有的大多数博客也比较旧了,不太合适,总结了这么几个方式吧,一起来学习下。

为什么要清除Android中这些资源呢

是这样的,今天收到的邮件里,有这么一条任务:

资源优化

  软件中无用的图片和布局文件,找到并验证是否无用.
       这个需要设计一套工具进行分析(自行设计最好或者第三方)

嗯,好吧...说笑了! 下面是正题↓↓↓↓

其实随着项目不断更新,需求不断变动,一改再改,UI一调再调,结果就是项目中一堆已经用不到但却没有清理的垃圾资源,不说工程大小问题,对新进入项目的人或看其他模块的代码的人来说,这些没清理的资源可能也可能会带来困扰,所以最好还是清理掉这些垃圾,对于一个稍微大一点的工程来说,手工清理明显是不现实的,这就需要一个方法做这些事情。

知识整合

看了很久,总结了一下,我能找到的市面上规划了一下大概有8种方法来做这件事,时间原因肯定不能全试啦,因为选出最合适的方法就要开始写成公司自己专门的工具了,简单说一下:

1.看到的第一个方法就是用SDK提供的代码检查工具Android lint

Android lint 删除无用图片文件和配置文件

  • Android lint 在 Android sdk tools 当中 配好环境变量(知道了Lint,这个工具非常强大!强烈推荐研究一下)
  • 输入:lint --check "UnusedResources" /Users/baozi/Dev/android/android > result.txt(可以把无用资源信息输出到result文件)
  • 打开result文件查看信息,会发现在哪一行,叫什么,都会给出相应的评价。
  • 删除:代码如下(非常重要)!借用文中的一句话就是:手工逐条删除 并不符合程序猿三大优秀品质 : 懒惰 没有耐心 骄傲
/** 
 * 删除 未使用的冗余资源(图片 xml布局) 
 *  
 * @param b 
 *  
 *            false 显示资源列表 
 *  
 *            true 显示资源列表 并删除资源 
 *  
 * @throws Exception 
 */  
private static void init(boolean b) throws Exception {  
  
    String encoding = "UTF-8"; // 字符格式  
    String projectPath = "/Users/baozi/Dev/shihui/android/";//Android工程所在地址  
    String filePath1 = "/Users/baozi";//result的所在路径  
    File file = new File(filePath1, "result.txt");//获取result.txt 文件 生成地址  
    if (file.isFile() && file.exists()) { // 判断文件是否存在  
        InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考虑到编码格式  
        BufferedReader bufferedReader = new BufferedReader(read);  
        String line = null;  
        while ((line = bufferedReader.readLine()) != null) {  
            if (line.contains("UnusedResources") && !line.contains("res/value") && !line.contains("appcompat")  
                    && !line.contains("res/xml")) {  
                // System.out.println(line);  
                int end = line.indexOf(":");  
                if (end != -1) {  
                    String file_end = line.substring(0, end);  
                    String f = projectPath + file_end;  
                    System.out.println(f);  
                    if (b) {  
                        new File(f).delete();  
                        System.out.println("删除成功");  
                    }  
                }  
  
            }  
  
        }  
        read.close();  
  
    }  
}  

  • projectPath : Android工程在硬盘中的位置
  • filePath1 : lint 运行结果 result.txt 所在的位置

方法 参数 传入false 仅打印结果 传入true 打印结果 并删除文件

填入正确的地址 就能批量执行删除未使用的 布局 & 图片 资源 (UnusedResources)

如果想要删除其它操作 请修改 筛选条件

&& !line.contains("res/xml")```

使用心得: 循环使用3-6次 能完成 删除全部未使用的资源 但是有些废弃的模块 存在代码以来关系 需要手工判断删除
缺点:判断不准确


2.一个自动清理Android项目无用资源的工具类及源码

原文点此处

优点:把上个方法中找出的无用资源的信息,再删除,整个步骤封装成了一个程序,并且对原GITHUB项目进行了优化:对用到的如string、style等资源进行了处理。
步骤代码较长,就不贴了,详细看原文。


3.Android Studio利用Gradle删除没有使用到的资源和代码文件

原文点此处

利用Gradle来优雅的去除没有用到的资源文件:

android {
        buildTypes {
            release {
                minifyEnabled true
                shrinkResources true
            }
        }
    }
    ```
    
    
   缺点:很多没有用到的类还是会被打包进去。去除无效代码的功能要依赖于混淆,混淆又是一个耗时的操作,还是没有彻底解决打包慢的问题。
    
当然也可以做一些忽略无用的代码优化,所以感觉还不错。

--------------------

## 4.利用python自动清除Android工程中的多余资源
[原文点此处](http://www.cnblogs.com/kaima/p/3588434.html)

该文是博主直接在公司使用的方法,如下:

#################################################

环境: win + python 2.7

作者:马波

邮箱:mabo02@baidu.com

部门:hao123-无线

说明:首次使用时lint分析会耗几分钟,请耐心等待。

使用前先clean工程,确保工程bin下重新生成dex,

以便lint进行分析。如果要lint重新分析多余

资源,需要删掉(2)txt记录文件,(1)(3)(4)需要

根据我们的实际工程手动设置。

如果清除资源后,工程缺少文件而报错(极少

情况),尝试通过svn恢复该文件即可。

#################################################
import subprocess
import re
import os
import time
import thread

(1)工程位置

projectPath="D:/hao123/code/client-android"

(2)lint输出txt记录文件

txt="D:/hao123_unused_res.txt"

(3)正则表达式,清除drawable和layout下多余的jpg/png/xml,

并且排除以sailor_|wenku_|zeus_|bdsocialshare_|floating_life_|weather_info_icon_|anthology_开头的文件

regex = re.compile(r"^res\(drawable(-land)?(-[xn]?mhlo)|layout)?\(?!(sailor_|wenku_|zeus_|bdsocialshare_|floating_life_|weather_info_icon_|anthology_))[0-9a-zA-Z_.]*.(jpg|png|xml)", re.IGNORECASE)

(4)lint.bat的位置

lint="D:/sdk/tools/lint.bat"

isgotTxt=False
def timer(interval):
while not isgotTxt:
print 'Lint is analyzing: %s'%time.ctime()
time.sleep(interval)

if not os.path.exists(txt):
thread.start_new_thread(timer, (5,))
cmd=lint+' --check "UnusedResources" "'+ projectPath +'" >'+txt
p = subprocess.Popen(cmd, shell = True,stdout = subprocess.PIPE,stdin = subprocess.PIPE,stderr = subprocess.PIPE)
p.wait()

fobj=open(txt,'r')
isgotTxt=True
i=0
j=0
for line in fobj:
#print str(i)+":"+line
match=regex.match(line)
if match:
i=i+1
filename=projectPath+"/"+match.group().replace('\',"\/")
try:
print filename
os.remove(filename)
j=j+1
print "was deleted!"
except WindowsError:
print "is not exists"
pass

print "Total Unused Resources = "+str(i)
print "Total deleted Resources = "+str(j)


虽然系统不一样,还是打算写python脚本来试一下。

--------------------
## 5.还有这几篇有关与AndroiStudio图形化操作 以及一个Android Clear工具,以及用jar的方式都大同小异了,下面做个总结,下面几篇文章也是有不同的帮助
[多方法批量删除Android中无用的资源(更新Android Studio2.1工具)](http://blog.csdn.net/byszy/article/details/50524816) 去除无用资源文件最方便的方法

[清除Android工程中没用到的资源](http://www.cnblogs.com/angeldevil/p/3725358.html) 去除无用java代码

[清理你的Android代码](http://my.oschina.net/lifj/blog/402541)

[找出代码中已有的BUG —— FindBugs](http://www.cnblogs.com/kayfans/archive/2012/06/18/2554022.html)

[去掉多余的jar包 —— ClassPath Helper](http://blog.csdn.net/zongxiao08/article/details/8578703)

### **一定要非常注意的点:**
**(1)被无用资源引用的资源不会被视为无用资源,所以需要重复执行多次,保证清除干净。**

**(2)删除资源文件之前要先删除无用java代码,否则容易报错,因为代码中还(可能)存在引用.**

**(3)一定要提交之后,再做备份在清除资源,你懂~**


--------------
# 我的思路
** 1. 清除Java代码** 

** 2. 找出无用资源** 

** 3. 按需清理** 

具体如下:

** 清除Java代码** 

* 安装Eclipse的UCDetector插件,对工程执行检查,结果会输出到一个文本文件中,同样是每个问题一行.
* 处理没用到的类文件

String reportPath = "**/ucdetector_reports/UCDetectorReport_001.txt";
BufferedReader reader = new BufferedReader(new FileReader(reportPath));
String line;
int count = 0;
while((line = reader.readLine()) != null) {
if (line.contains("Class") && line.contains("has 0 references") && !line.contains("Method")[ && other conditions]) {
count++;
int end = line.indexOf(".<init>");
if (end != -1){
String className = line.substring(0, end);
System.out.println(className);
}
}
}


* 过滤不想删除的


**  找出无用资源 && 按需清理** 

在最新的版本(Studio2.1)中,lint已经可以自行删除无用资源,这样的话,我们的python脚本也不需要写了(2.1以下还是自行写脚本),具体操作如下: 

* Ctrl+Shift+Alt+I 弹出一个框,输入UnusedResources,弹出下图

![](http://upload-images.jianshu.io/upload_images/2470576-23d82fb97b1763a9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

* 点击OK,出来下图



![](http://upload-images.jianshu.io/upload_images/2470576-8185a45a030ab7d7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

我们选择Remove All Unused Resources。片刻后(工程大可能会比较久,1-2min?)弹出一个确认对话框,确认之 。

---------------
上述提到的LINT:

静态代码分析工具,无需运行,无需测试用例

扫描整个项目,分析以下潜在的问题,分类指出问题描述、问题位置,并提供合理的修改建议(这是才是关键啊,不管有木有大问题,看看这些问题及描述,也能过把瘾啊):
> 
> 1)性能
 布局性能(以前是 layoutopt工具,可以解决无用布局、嵌套太多、布局太多、overdraw)
 其他性能(如:draw/layout 时进行对象的声明等)
 
> 2)未使用到资源、资源缺少(不同资源的适配)

> 3)有更高性能的资源替换   ---- eg:SparseBooleanArray SparseIntArray 

> 4)国际化问题(硬编码)

> 5)图标的问题(重复的图标,错误的大小)

> 6)可用性问题(如不指定的文本字段的输入型)

> 7)manifest文件的错误 -- 未注册activity service等等

> 8)内存泄露 --- 如:handle的不当使用 。 

> 9)占内存的资源及时回收  --- 如:TypedArray未回收资源等

附:

[Android性能优化之LINT使用总结](http://blog.csdn.net/Rflyee/article/details/43164589)

[Improve Your Code with Lint](https://developer.android.com/studio/write/lint.html)  google文档
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,193评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,306评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,130评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,110评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,118评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,085评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,007评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,844评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,283评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,508评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,395评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,985评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,630评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,797评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,653评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,553评论 2 352

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,061评论 25 707
  • afinalAfinal是一个android的ioc,orm框架 https://github.com/yangf...
    passiontim阅读 15,427评论 2 45
  • 在重庆的那些日子,每天早上起来,站立于窗前,眼前灰蒙蒙的一片。远远望去,整个一雾中城,没有一处稀薄,雾气均匀的笼罩...
    掬手留香阅读 282评论 4 2
  • 从小到大的生活环境 造就了我 在没有过分喧嚷的嘈杂中 也能一心看书 有时甚至觉得 习惯成了一种方式 太安静 反而...
    枫子fengzi阅读 122评论 0 0