andorid之app抽离module及自动化加载全部资源


一、来源:

   随着公司的发展,项目越来越大以及项目组之间要公用代码,那么最好的方式将其它项目组所需要的功能抽离成一个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项目来运行的,也可以自己搞插件,自行处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值