正則表達式獲取註釋 不是註解

場景

要找到@hide標註的方法。遺憾的是,@hide標註的類或者方法都是寫在註釋中的,Google爲啥這麼搞,說實話沒弄明白爲啥放在註釋裏面,不放在註解中。要找出所有的@hide的API在apk中的應用,這個有工具的,只是當時不太清楚,想着通過找到@hide的方法,然後在對比,在文章的末尾給出解決辦法,用的是google的一個腳本。

假設

  1. 註釋的形式是/** */這種格式的
  2. 獲帶有取@Deprated的方法
  3. 在/** */註釋中的內容不包含"/"
    注意:?代表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

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