本文研究的主要是StackTraceElement獲取方法調(diào)用棧信息的相關(guān)內(nèi)容,具體介紹和實(shí)例如下。
創(chuàng)新互聯(lián)主要從事成都網(wǎng)站建設(shè)、成都做網(wǎng)站、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)柳城,十載網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18982081108
StackTrace(堆棧軌跡)存放的就是方法調(diào)用棧的信息,異常處理中常用的printStackTrace()實(shí)質(zhì)就是打印異常調(diào)用的堆棧信息。
StackTraceElement表示StackTrace(堆棧軌跡)中的一個(gè)方法對象,屬性包括方法的類名、方法名、文件名以及調(diào)用的行數(shù)。
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,可見其作為一個(gè)java的基礎(chǔ)類不允許被繼承。
獲取StackTraceElement的方法有兩種,均返回StackTraceElement數(shù)組,也就是這個(gè)棧的信息。
1、Thread.currentThread().getStackTrace()
2、new Throwable().getStackTrace()
StackTraceElement數(shù)組包含了StackTrace(堆棧軌跡)的內(nèi)容,通過遍歷它可以得到方法間的調(diào)用過程,即可以得到當(dāng)前方法以及其調(diào)用者的方法名、調(diào)用行數(shù)等信息
public class TestClass { public static void main(String[] args) { new TestClass().methodA(); } private void methodA(){ System.out.println("------進(jìn)入methodA----------"); methodB(); } private void methodB(){ System.out.println("------進(jìn)入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數(shù)組下標(biāo) i="+i+",fileName=" +fileName+",className="+className+",methodName="+methodName+",lineNumber="+lineNumber); } } }
1、我們可以封裝一個(gè)日志庫,在打印目標(biāo)日志的時(shí)候,也可以通過這個(gè)調(diào)用棧打印出這個(gè)日志所在的行數(shù),這樣就可以迅速的定位到日志輸出行,再也不要全局搜索去查找了。
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、如果我們寫了一個(gè)SDK,希望某個(gè)方法在固定的位置被調(diào)用,我們也可以在這個(gè)方法被調(diào)用的時(shí)候,進(jìn)行檢查,看這個(gè)方法的調(diào)用位置是否正確。
例如,必須在Activity.onResume中執(zhí)行,PVSdk.onResume,所以我們在調(diào)用PVSdk.onResume方法的時(shí)候,在PVSdk.onResume方法里面來通過獲取調(diào)用棧的信息檢測這個(gè)方法是否在Activity的onResume方法中調(diào)用的。
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、我們在進(jìn)行源碼分析的時(shí)候,如果想分析整個(gè)代碼的執(zhí)行流程,我們可以進(jìn)行通過打印棧的信息來獲取,這個(gè)在源碼分析的時(shí)候還是挺有用的。
以上就是本文關(guān)于StackTraceElement獲取方法調(diào)用棧信息實(shí)例詳解的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!