場景
要找到@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”
參考鏈接
https://blog.csdn.net/helloworlddm/article/details/89735482
https://blog.csdn.net/helloworlddm/article/details/102766902