一、来源:
随着公司的发展,项目越来越大以及项目组之间要公用代码,那么最好的方式将其它项目组所需要的功能抽离成一个module公共库,直接提供给他们用,这时候就会遇到重复性移动java类以及layout等等引用到的所需要的资源如drawable、layout、style、string、color、selector之类的,这如果手动移动很枯燥,也很耗时,主要是耗时,尤其是项目越大牵扯越多,资源牵扯就更多,这时候就特想一键将所需要的资源从主app移动到module以及将资源从app中移除,这时候这种自动化工具就从想法中油然而生。。。。
二、前提工作:
使用自动化的前期工作也是必不可少的手动移植工作如下:
1、使用自动化脚本之前,请先将app要抽离的所有java类都移到module,然后在跑自动化自动加载所需要的资源
2、移动java类到module的目录,一定要记得保持和app中java类所在的目录一模一样,避免报名不一样导致各种应用错误
3、 可以使用快捷键:选中文件alt+shift+v选择target directory 为module,然后选中一模一样的路径,android studio会 自动创建一样的报名 或者 选中文件右键--move--重复快捷键的操作方式
注:也可整个报名一起移动
三、思路:一切的程序都是由简到难,从中分析找到所需规律
1、通过递归遍历所有目录下的所有文件
2、每递归一个目录得到这个目录下的所有文件,将所有文件一个个查找
3、遍历一个文件得到资源要查找的所有资源文件名集合
4、通过资源名集合,查找源文件(比如style.xml或strings.xml或者.png的所有目录等等)得到资源名(strings.xml style.xml)所在源文件的行号集合(过程中已经去重)
(drawable下则是通过查找所有drawable的目录,找到后直接将文件复制到目标目录,并且删除源文件(原图片))
5、一个资源名的行号集合:到源文件下找到对应的行号集合就是要写到目标文件的行内容,接下来准备写入目标style.xml或color.xm或strings.xml
6、写入目标文件前,判断当前资源名是否已经写入,已写入则不再进行读写,未写入,则将当前的行号集合对应的行内容追加到目标文件末尾,并将这个行号集合加入到一个static集合
7、当递归完所有文件后,得到已写入目标文件的所有资源名对应在源文件的所有行号集合,接下来要统一删除这些已写入目标文件的资源定义
8、删除之前,先将源文件备份(会自动备份保存在同一目录下名为xxxbackup.xml)防止出错,之后再删除
9、手动将</resource>移动在追加文件之后,这就完成了
注:运行时,一定要先检查路径,替换成自己相应的路径
剩下的就直接看代码:应该也不难,分的也还算清楚,每个文件对一个内容操作,这里只分享众多文件中的一个代码,其余可在最后下载demo,自行分析,望对你有帮助,有不对的地方,请不吝指正
package www.file;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* java文件读取R.drawble.xxx图片文件工具类
*
* @author zhongwr
*
*/
public class DrawableFileUtil {
/**
* 查找并移动所有文件 zhongwr 下午3:02:50 void
*/
public static void moveAllFile(String fileDir) {
File f = new File(fileDir);
if (f != null) {
if (f.isDirectory()) {
File[] fileArray = f.listFiles();
if (fileArray != null) {
for (int i = 0; i < fileArray.length; i++) {
// 递归调用
// System.out.println("文件目录 : " + f.getAbsolutePath());
moveAllFile(fileArray[i].getAbsolutePath());
}
}
} else {// 操作所有
// System.out.println("文件路径:" + f.getAbsolutePath());
executejavaFile(f);
}
}
}
/**
* java文件中用的图片文件名R.drawable.xxxx 下午7:52:26 void
*/
private static void executejavaFile(File f) {
// java中用的图片文件名R.drawable.xxxx
List<String> fileNameList = getJavaDrawFileName(f.getAbsolutePath());
// System.out.println("java中的draw = " + fileNameList.toString());
if (null != fileNameList && !fileNameList.isEmpty()) {
List<String> absolutePathList = getSrcDrawFileName(fileNameList);
int size = absolutePathList.size();
String fileAbsolutePath = "";
for (int i = 0; i < size; i++) {
fileAbsolutePath = absolutePathList.get(i);
// System.out.println("fileAbsolutePath = " + fileAbsolutePath);
//路径是双\\所以得两个,虽然打印的时候是单个\
String copySuffixPath = fileAbsolutePath.split("(\\\\res)")[1];
// System.out.println("后缀 = " + copySuffixPath);
copyFile(fileAbsolutePath,
// "D:\\copyjavadrawfile\\" + copySuffixPath);
"D:\\soft\\studio_project\\PPTest\\lib_preg_home\\src\\main\\res" + copySuffixPath);
deletFile(fileAbsolutePath);
}
}
}
/**
* 复制单个文件:
*
* @param oldPath
* String 原文件路径 如:c:/fqf.txt
* @param newPath
* String 复制后路径 如:f:/fqf.txt
* @return boolean
* @author zhongwr
*/
public static void copyFile(String oldPath, String newPath) {
try {
// System.out.println("oldPath = " + oldPath + " \\n newPath = " + newPath);
int byteread = 0;
File newfile = new File(newPath);
if (new File(newPath).exists()) {
System.out.println("文件已存在 : " + newPath);
return;
}
if (!newfile.getParentFile().exists()) {
boolean isOk = newfile.getParentFile().mkdirs();
System.out.println("isOk = " + isOk);
}
File oldfile = new File(oldPath);
if (oldfile.exists()) { // 文件存在时
InputStream inStream = new FileInputStream(oldPath); // 读入原文件
FileOutputStream fs = new FileOutputStream(newPath);
byte[] buffer = new byte[inStream.available()];
while ((byteread = inStream.read(buffer)) != -1) {
fs.write(buffer, 0, byteread);
}
inStream.close();
System.out.println("复制文件成功 = " + oldPath);
} else {
System.out.println("文件不存在 ");
}
} catch (Exception e) {
System.out.println("复制单个文件操作出错");
e.printStackTrace();
}
}
/**
* 删除文件
* <p>
* false 显示资源列表
* <p>
* true 显示资源列表 并删除资源
*
* @throws Exception
*/
public static void deletFile(String filePath) {
File file = new File(filePath);
// System.out.println("file.isFile() = " + file.isFile());
if (file.isFile() && file.exists()) { // 判断文件是否存在
try {
file.delete();
System.out.println("删除成功: "+filePath);
} catch (Exception e) {
}
}
}
/**
* 读取单个java文件内容,并获取R.drawable.xxx中的xxx文件名
*/
public static List<String> getJavaDrawFileName(String javaFileName) {
List<String> filePathList = new ArrayList<String>();
try {
BufferedReader reader = new BufferedReader(new FileReader(javaFileName));
String line;
String fileName = null;
while ((line = reader.readLine()) != null) {
if (line.contains("R.drawable.")) {
String[] fileArr = line.split("R.drawable.");
if (null != fileArr && fileArr.length >= 2) {
if (fileArr[1].contains(",")) {// 考虑到setTag(R.drawable.xxx,"")
fileName = fileArr[1].split("[,]")[0];
} else {// 剩下都是(R.drawable.xxx)
fileName = fileArr[1].split("[)]")[0];
}
// System.out.println(" R.drawable.fileName = " + fileName);
filePathList.add(fileName);
}
}
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
return filePathList;
}
/**
* 获取源文件图片的绝对路径
*
* @author zhongwr 下午4:40:24
* @param fileNameList
* 文件名集合
*/
public static List<String> getSrcDrawFileName(List<String> fileNameList) {
List<String> absoluteFileList = new ArrayList<String>();
try {
int size = fileNameList.size();
String fileName = "";
String absoluteFilePath = null;
for (int i = 0; i < size; i++) {
fileName = fileNameList.get(i);
// drawable
absoluteFilePath = getDrawAbsolutePath(
"D:\\soft\\studio_project\\PPTest\\app\\src\\main\\res\\drawable\\", fileName);
if (null != absoluteFilePath) {
absoluteFileList.add(absoluteFilePath);
}
// drawable-hdpi
absoluteFilePath = getDrawAbsolutePath(
"D:\\soft\\studio_project\\PPTest\\app\\src\\main\\res\\drawable-hdpi\\", fileName);
if (null != absoluteFilePath) {
absoluteFileList.add(absoluteFilePath);
}
// drawable-xhdpi
absoluteFilePath = getDrawAbsolutePath(
"D:\\soft\\studio_project\\PPTest\\app\\src\\main\\res\\drawable-xhdpi\\", fileName);
if (null != absoluteFilePath) {
absoluteFileList.add(absoluteFilePath);
}
// drawable-xxhdpi
absoluteFilePath = getDrawAbsolutePath(
"D:\\soft\\studio_project\\PPTest\\app\\src\\main\\res\\drawable-xxhdpi\\", fileName);
if (null != absoluteFilePath) {
absoluteFileList.add(absoluteFilePath);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return absoluteFileList;
}
/**
* 获取文件源文件的绝对路径 zhongwr 下午4:54:52 String
*/
private static String getDrawAbsolutePath(String srcDrawDir, String targetFileName) {
String absoluteFilePath = null;
File f = new File(srcDrawDir);
if (f != null) {
if (f.isDirectory()) {
File[] fileArray = f.listFiles();
if (fileArray != null) {
int size = fileArray.length;
String srcFileName = null;
for (int i = 0; i < size; i++) {
// System.out.println("draw 文件名 = " + fileArray[i].getName());
srcFileName = fileArray[i].getName().split("[.]")[0];
if (srcFileName.equals(targetFileName)) {
absoluteFilePath = fileArray[i].getAbsolutePath();
// System.out.println("draw 绝对路径 = " + absoluteFilePath);
}
}
}
}
}
return absoluteFilePath;
}
}
demo:http://download.csdn.net/detail/zhongwn/9660341
demo是使用Java项目来运行的,也可以自己搞插件,自行处理