1、思路:因为布局文件一般用到字符串的地方有两个:android:text="测试"或者android:hint="测试",所以可以用正则表达式把它们拿到,并写到strings.xml中,string的name自动生成,比如str_1、str_2,然后把它们的对应关系保存到hashmap中。最后,遍历所有的xml文件,进行替换。
2、下面的SearchAndroidTextFileUtils和SearchAndroidText是进行android:text="测试"这种格式的string的抽出替换工作的。使用的时候,只需把SearchAndroidText类的main方法dirPath变量变成你实际的,就可以了。抽取替换android:hint="测试"这种string时,只需把文件中的android:text替换成android:hint就行了。
package com.ivan.demo.utils;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 文件操作工具类
* Created by ivan on 2018/8/8.
*/
public class SearchAndroidTextFileUtils {
private static Map hashMap = new HashMap();//保存写到auto_create_strings.xml文件的key和value
/**
* 读取文件的内容
*
* @param file 想要读取的文件对象
* @return 返回已经存在的string数据
*/
public static List getExistString(File file) {
List result = new ArrayList<>();
try {
BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件
String s = null;
while ((s = br.readLine()) != null) {//使用readLine方法,一次读一行
if (!s.contains("") && !s.contains(" ") && s.contains(" ")) {
System.out.println(s);//TODO
result.add(s);
}
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* @param file
* @param oldStringList 旧的string数据
* @param newStringList 新的string数据
*/
public static void writeFile(File file, List oldStringList, List newStringList) {
FileWriter fw = null;
BufferedWriter bw = null;
try {
fw = new FileWriter(file);
bw = new BufferedWriter(fw);
bw.write("\r\n");
int index = 1;
if (oldStringList != null && !oldStringList.isEmpty()) {
for (int i = 0; i < oldStringList.size(); i++) {
bw.write(oldStringList.get(i) + "\r\n");
index++;
}
}
for (int i = 0; i < newStringList.size(); i++) {
String key = "str_" + index;
String value = newStringList.get(i);
bw.write("");
bw.write(value.replace(" ", " "));//strings.xml的空格转义
bw.write(" \r\n");
index++;
hashMap.put(key, value);
}
bw.write(" \r\n");
bw.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 替换布局文件中的string硬编码
*
* @param file
* @param keyWord
*/
public static void replaceStringByAt(File file, String keyWord) {
String encoding = "UTF-8";
Long filelength = file.length();
byte[] filecontent = new byte[filelength.intValue()];
FileInputStream in = null;
try {
in = new FileInputStream(file);
in.read(filecontent);
in.close();
String content = new String(filecontent, encoding);
Pattern pat = Pattern.compile(keyWord);
Matcher mat = pat.matcher(content);
while (mat.find()) {
String resultStr = mat.group(0);
String oldStr = resultStr.replace("android:text=\"", "");
oldStr = oldStr.substring(0, oldStr.length() - 1);
if (!oldStr.contains("@string/")) {
String newStr = "android:text=\"" + getReplaceStr(oldStr) + "\"";
content = content.replace(resultStr, newStr);
}
}
FileWriter fout = new FileWriter(file);// 创建文件输出流
fout.write(content.toCharArray());// 把替换完成的字符串写入文件内
fout.close();// 关闭输出流
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static String getReplaceStr(String search_value) {
String result = "";
Iterator> iter = hashMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
String key = entry.getKey();
String val = entry.getValue();
if (search_value.equals(val)) {
return "@string/" + key;
}
}
return result;
}
}
package com.ivan.demo;
import com.ivan.demo.utils.SearchAndroidTextFileUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
//查找layout目录下的布局文件中的中文硬编码,抽出到auto_create_strings.xml,替换
public class SearchAndroidText {
private static List stringList = new ArrayList<>();
public static void readToString(String fileName, String keyWord) {
String encoding = "UTF-8";
File file = new File(fileName);
Long filelength = file.length();
byte[] filecontent = new byte[filelength.intValue()];
FileInputStream in = null;
try {
in = new FileInputStream(file);
in.read(filecontent);
in.close();
String content = new String(filecontent, encoding);
Pattern pat = Pattern.compile(keyWord);
Matcher mat = pat.matcher(content);
while (mat.find()) {
String resultStr = mat.group(0);
String resultKey = resultStr.replace("android:text=\"", "");
resultKey = resultKey.substring(0, resultKey.length() - 1);
if (!resultKey.contains("@string/")) {
stringList.add(resultKey);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void searchFile(File folder, final String keyWord) {// 递归查找包含关键字的文件
File[] subFiles = folder.listFiles();
if (subFiles == null) {
return;
}
for (int i = 0; i < subFiles.length; i++) {// 循环遍历文件夹或文件
if (subFiles[i].isFile()) {
if (subFiles[i].getName().endsWith(".xml")) {
//System.out.println(subFiles[i].getName());
readToString(subFiles[i].getAbsolutePath(), keyWord);
}
} else if (subFiles[i].isDirectory()) {// 如果是文件夹,则递归调用本方法
searchFile(subFiles[i], keyWord);
}
}
}
//去掉重复string
public static List removeDuplicate(List list) {
List listTemp = new ArrayList();
for (int i = 0; i < list.size(); i++) {
if (!listTemp.contains(list.get(i))) {
listTemp.add(list.get(i));
}
}
return listTemp;
}
public static void main(String[] args) throws Exception {// java程序的主入口处
String dirPath = "D:\\code\\studio\\StringInternationalDemo\\app\\src\\main\\res\\";
File folder = new File(dirPath + "layout");// 默认目录
String keyword = "android:text=\".*?\"";//?表示贪婪模式
if (!folder.exists()) {// 如果文件夹不存在
System.out.println("目录不存在:" + folder.getAbsolutePath());
return;
}
//第一步:查找布局文件中的中文硬编码
searchFile(folder, keyword);
stringList = removeDuplicate(stringList);
//第二步:在values文件夹下创建auto_create_strings.xml
File file = new File(dirPath + "values\\" + "auto_create_strings.xml");
List existStringList = new ArrayList<>();//保存已经存在的string数据
if (!file.exists()) {//如果文件不存在,则创建一个
file.createNewFile();
} else {//如果存在则获取已经存在的string数据
existStringList = SearchAndroidTextFileUtils.getExistString(file);
}
//第三步:往auto_create_strings.xml文件写内容
SearchAndroidTextFileUtils.writeFile(file, existStringList, stringList);
//第四步:替换layout文件中每一个xml文件的string硬编码
File[] xmlFiles = folder.listFiles();
for (int i = 0; i < xmlFiles.length; i++) {
File xFile = xmlFiles[i];
SearchAndroidTextFileUtils.replaceStringByAt(xFile, keyword);
}
}
}
3、代码下载地址