本文研究的主要是StackTraceElement獲取方法調用棧信息的相關內容,具體介紹和實例如下。
StackTrace(堆棧軌跡)存放的就是方法調用棧的信息,異常處理中常用的printStackTrace()實質就是打印異常調用的堆棧信息。
StackTraceElement表示StackTrace(堆棧軌跡)中的一個方法對象,屬性包括方法的類名、方法名、文件名以及調用的行數。
public final class StackTraceElement implements java.io.Serializable {// Normally initialized by VM (public constructor added in 1.5) private String declaringClass;private String methodName;private String fileName;private int lineNumber;}StackTraceElement被定義為final,可見其作為一個java的基礎類不允許被繼承。
獲取StackTraceElement的方法有兩種,均返回StackTraceElement數組,也就是這個棧的信息。
1、Thread.currentThread().getStackTrace()
2、new Throwable().getStackTrace()
StackTraceElement數組包含了StackTrace(堆棧軌跡)的內容,通過遍歷它可以得到方法間的調用過程,即可以得到當前方法以及其調用者的方法名、調用行數等信息
public class TestClass {public static void main(String[] args) {new TestClass().methodA();}private void methodA(){System.out.println("------進入methodA----------");methodB();}private void methodB(){System.out.println("------進入methodB----------");StackTraceElement elements[] = Thread.currentThread().getStackTrace();for (int i = 0; i < elements.length; i++) {StackTraceElement stackTraceElement=elements[i];String className=stackTraceElement.getClassName();String methodName=stackTraceElement.getMethodName();String fileName=stackTraceElement.getFileName();int lineNumber=stackTraceElement.getLineNumber();System.out.println("StackTraceElement數組下標i="+i+",fileName=" +fileName+",className="+className+",methodName="+methodName+",lineNumber="+lineNumber);}}}1、我們可以封裝一個日誌庫,在打印目標日誌的時候,也可以通過這個調用棧打印出這個日誌所在的行數,這樣就可以迅速的定位到日誌輸出行,再也不要全局搜索去查找了。
public static void d(String tag, String msg, Object... params) { StackTraceElement targetStackTraceElement = getTargetStackTraceElement(); Log.d(tag, "(" + targetStackTraceElement.getFileName() + ":" + targetStackTraceElement.getLineNumber() + ")"); Log.d(tag, String.format(msg, params));}2、如果我們寫了一個SDK,希望某個方法在固定的位置被調用,我們也可以在這個方法被調用的時候,進行檢查,看這個方法的調用位置是否正確。
例如,必須在Activity.onResume中執行,PVSdk.onResume,所以我們在調用PVSdk.onResume方法的時候,在PVSdk.onResume方法裡面來通過獲取調用棧的信息檢測這個方法是否在Activity的onResume方法中調用的。
public class PVSdk {public static void onResume() {StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();Boolean result = false;for (StackTraceElement stackTraceElement : stackTrace) {String methodName = stackTraceElement.getMethodName();String className = stackTraceElement.getClassName();try {Boolean assignableFromClass = Class.forName(className).isAssignableFrom(Activity.class);if (assignableFromClass && "onResume".equals(methodName)) {result = true;break;}}catch (ClassNotFoundException e) {}}if (!result) throw new RuntimeException("PVSdk.onResume must in Activity.onResume");}}3、我們在進行源碼分析的時候,如果想分析整個代碼的執行流程,我們可以進行通過打印棧的信息來獲取,這個在源碼分析的時候還是挺有用的。
以上就是本文關於StackTraceElement獲取方法調用棧信息實例詳解的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!