Android项目经过长期的迭代开发,项目当中有大量无用的冗余资源,如果不整理将会导致apk包比较大。
在这里,我使用的是Android sdk tools中自带的Lint工具。
一、直接在Eclipse中使用。
右键需要清理的项目 -> Android Tools -> Run Lint:Check For Common Errors 这时就会打开Lint warning 视图,在这里就可以清理各种无用的资源、代码。
这种方式比较简单,但是需要你自己手动清理,如果项目比较大,就会繁琐无比。
二、Dos下使用命令行。
1,进入Dos,如果没有配置环境变量,那就cd到lint批处理文件所在目录
2,lint --check "UnusedResources" project路径 > 存放路径/result.txt
使用这行命令,lint会把需要清理的project检索,生成一个结果文件,可以打开这个文件,发现都是一些无用资源的路径信息。
3,解析result结果文件,删除无用资源。
解析的方式就多种多样了,既可以写一个批处理,也可以是exe,当然,最简单的还是写个java类:
private static String encoding = "UTF-8"; // 字符格式 private static String projectPath = "";//Android工程所在地址 private static String filePath = "";//result的所在路径 public static void main(String[] args) { try { init(false); } catch (Exception e) { e.printStackTrace(); } } private static void init(boolean autoDelete) throws Exception { File file = new File(filePath, "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"+File.separator+"value") && !line.contains("appcompat") && !line.contains("res"+File.separator+"xml")) { int end = line.indexOf(":"); if (end != -1) { String file_end = line.substring(0, end); String f = projectPath + file_end; System.out.println(f); if (autoDelete) { new File(f).delete(); System.out.println("删除成功"); } } } } read.close(); } }这里可以先设置aotoDelete为false,这样执行后只会打印需要删除的资源,检查发现没有问题后,再改为true就会自动删除了。
最后,提供一种更好的解决方法,result文件的生成以及无用资源的删除,都在一个java类中搞定:
public static final String separator = File.separator; public static void clearRes(boolean autoDelete, String lintPath, String projectPath, String[] dirArray) { Process process = null; InputStream is = null; InputStreamReader isr = null; BufferedReader br = null; FileWriter fw = null; String cmd = lintPath + " --check UnusedResources " + projectPath; int fileCount = 0; long fileSize = 0; try { SimpleDateFormat formatter = new SimpleDateFormat( "yyyy-MM-dd-HH-mm-ss"); Date curDate = new Date(System.currentTimeMillis()); String dateStr = formatter.format(curDate); fw = new FileWriter(projectPath + separator + dateStr + ".txt", true); Runtime runtime = Runtime.getRuntime(); String line = null; process = runtime.exec(cmd); is = process.getInputStream(); isr = new InputStreamReader(is); br = new BufferedReader(isr); while ((line = br.readLine()) != null) { for (String dir : dirArray) { if (line.startsWith("res" + separator + dir)) { int index = line.indexOf(":"); if (index > 0) { String filePath = projectPath + separator + line.substring(0, index); if (null != filePath && !"".equalsIgnoreCase(filePath)) { filePath = filePath.replaceAll("/", "\\\\"); } ++fileCount; File file = new File(filePath); fileSize += file.length(); System.out.println("unused file: " + filePath); if (autoDelete) { boolean success = file.delete(); System.out.println(filePath + " " + success); fw.write(filePath + " " + success + "\n"); fw.flush(); } } break; } } } String result = "delete file " + fileCount + ",save space " + fileSize / 1024 + "KB."; System.out.println(result); fw.write(result); fw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (fw != null) { try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } if (process != null) { process.destroy(); } } } public static void main(String[] args) { if (args.length < 2) { System.out .println("Please config program arguments. Correct arguments contain both absolute path of lint.bat and that of android project."); return; } String lintPath = args[0]; String projectPath = args[1]; String[] dirArray = { "drawable", "layout", "anim", "color" }; CURes.clearRes(true, lintPath, projectPath, dirArray); }
D:/software/adt-bundle-windows-x86_64/sdk/tools/lint.bat
E:/work_space/myproject
注意lint路径需要把lint.bat也加上,传入路径必须是正斜杠。
(以上代码,都经过验证和使用,完全可以直接运行)
新发现个小问题,eclipse在使用过lint后会出现打包apk失败,这是因为开启了lint的自动检测,
去eclipse Preferences 选择 Android 下 Lint Error Checking
去掉勾选项 "Run full error check when exporting app and abort if fatal errors are found "