利用new Exception() getStackTrace()檢視誰呼叫了方法

pdog發表於2017-12-14

過時的方法 使用 AS debug模式可以很輕易的獲得呼叫棧

最近專案中遇到一個Bug ,在某次進行資料持久化的時候,對於同一個key的資料儲存。 在某次執行持久化時,將一個valuenull的值覆蓋上去了,但是專案中有非常多的地方對這個key進行了持久化儲存。 才開始以為是非同步的問題,所以先將儲存方式改為同步後發現錯誤依然存在。 如果要一個一個排查的話那麼將會花費大量的精力。 那麼能不能在資料持久化的入口中檢視到底是哪個方法呼叫的時候覆蓋了不正確的值呢?

這時想起來KLoglog工具類實現自動新增類名,方法名的一個挺巧妙的辦法。

通過new Exception().getStackTrace();可以獲得方法的呼叫棧的陣列,那麼就可以在持久化的入口處獲得傳入不正確值的方法呼叫棧了。

//程式碼大致如下
StackTraceElement[] stackTrace = new Exception().getStackTrace();
        for (int i = 0; i < stackTrace.length; i++) {
            System.out.println("key = " + stackTrace[i]);
        }
複製程式碼

當然程式碼中的層級數i < stackTrace.length 你可以同時再加個判斷i < stackTrace.length && i <5 ,不然的話日誌就會一直列印到Android程式的入口即ZygoteInit.main(), 就像這樣


//...上層程式碼忽略
android.os.Handler.handleCallback(Handler.java:815)
android.os.Handler.dispatchMessage(Handler.java:104)
android.os.Looper.loop(Looper.java:207)
android.app.ActivityThread.main(ActivityThread.java:5896)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:948)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:809)
複製程式碼

相關文章