场景
要找到@hide标注的方法。遗憾的是,@hide标注的类或者方法都是写在注释中的,Google为啥这么搞,说实话没弄明白为啥放在注释里面,不放在注解中。要找出所有的@hide的API在apk中的应用,这个有工具的,只是当时不太清楚,想着通过找到@hide的方法,然后在对比,在文章的末尾给出解决办法,用的是google的一个脚本。
假设
- 注释的形式是/** */这种格式的
- 获带有取@Deprated的方法
- 在/** */注释中的内容不包含"/"
注意:?代表0个或者1个。
代码及注释
版本一
package test;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
/** @Hide*/
public static void test(){
System.out.println("Burning");
}
public static void main(String[] args) throws IOException {
/*String content = "This order was placed for Qt300! ok?";
String regexPat = "(\\D*)(\\d*)(.*)";
Pattern pattern = Pattern.compile(regexPat);
Matcher match = pattern.matcher(content);
System.out.println(match.groupCount());
if (match.find()){
System.out.println("Found value "+match.group(0));
System.out.println("Found value "+match.group(1));
System.out.println("Found value "+match.group(2));
System.out.println("Found value "+match.group(3));
}else{
System.out.println("not matched");
}*/
FileInputStream fis = new FileInputStream("D:\\liebao\\test\\Test.java");
byte[] buff = new byte[fis.available()];
//通过这种方式,可以读取到所有的文件内容
fis.read(buff);
String regexPat = "(\\/\\*.*@Hide.*\\*\\/.*test)";
Pattern pattern = Pattern.compile(regexPat);
String str = new String(buff);
//通过测试发现Java正则表达式只是匹配一行,所以这里对"\r"和"\n"进行替换
String str1 = str.replace("\n", " ").replace("\r", " ");
System.out.println(str1.length());
Matcher match = pattern.matcher(str1);
if (match.find()){
System.out.println("Found value "+match.group(1));
}else{
System.out.println("not matched");
}
// boolean ret = Pattern.matches("\\/\\*.*@Hide.*\\*\\/.*test", str1);
// System.out.println("ret = "+ret);
}
版本2
package test;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) throws IOException {
Class test = Test.class;
Method[] methods = test.getDeclaredMethods();
for (Method method : methods) {
//获取方法的返回值类型 如果是void,这返回,如果是Java.lang.String的话则进行截取,获取最后一个字段
Class<?> returnType = method.getReturnType();
String name = returnType.getName();
boolean ret = false;
String[] arr = name.split("\\.");
String type = "";
if (arr.length > 0){
type = arr[arr.length-1];
}else{
type = arr[0];
}
//判断方法是否是static方法
ret = Modifier.isStatic(method.getModifiers());
//捕获组中的最后一部分
//匹配 public 空格(0-n个) static? 空格(0-n个) 返回值类型 空格(0-n个) 方法名
String methodSig = "public\\s*"+(ret == true?"static":"")+"\\s*"+type+"\\s*"+method.getName();
getMethodNotes(methodSig);
}
}
public static void getMethodNotes(String methodSig) throws IOException {
FileInputStream fis = new FileInputStream("D:\\liebao\\test\\Test.java");
byte[] buff = new byte[fis.available()];
fis.read(buff);
//捕获组1是匹配//* */,在这期间不能有"/"
//捕获组2匹配的是 @Deprecated
String regexPat = "(\\/\\*\\*[^\\/]*@return[^\\/]*\\*\\/)(\\s*@Deprecated)(\\s*"+methodSig+")";
Pattern pattern = Pattern.compile(regexPat);
String str = new String(buff);
String str1 = str.replace("\n", " ").replace("\r", " ");
Matcher match = pattern.matcher(str1);
if (match.find()){
System.out.println("Found value 001:"+match.group(1));
System.out.println("Found value 002:"+match.group(2));
System.out.println("Found value 003:"+match.group(3));
}else{
System.out.println("not matched!");
}
}
/**
* test method is valid.
* @return
*/
@Deprecated
public static String get(){
return "Hello world";
}
/**
* test 0009 is valid.
* @return
*/
@Deprecated
public static String set(){
return "Hello world";
}
}
运行结果
not matched!
Found value 001:/** * test method is valid. * @return /
Found value 002: @Deprecated
Found value 003: public static String get
Found value 001:/* * test 0009 is valid. * @return */
Found value 002: @Deprecated
Found value 003: public static String set
not matched!
代码注释稍后补上,12点了该休息了。play了5局dota,才开始看这个,哎,时间浪费的有点多呀。
在apk中寻找使用@hide的方法
The following from Google:
You can use the appcompat script available in the android tree to find all @hide usages from your APK’s:
./art/tools/veridex/appcompat.sh --dex-file=.apk grep -e “Linking.*android/net/wifi”