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項目來運行的,也可以自己搞插件,自行處理

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章