一、來源:
隨着公司的發展,項目越來越大以及項目組之間要公用代碼,那麼最好的方式將其它項目組所需要的功能抽離成一個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項目來運行的,也可以自己搞插件,自行處理