通过StackTrace获取方式名 · 老默笔记

电脑杂谈  发布时间:2020-02-18 08:00:41  来源:网络整理

stack trace 什么意思_java stack trace_java 方法调用 trace

开发过程中一直需要获得当前正在执行的方式名,以前搜过,只是简单的明白可以调用Thread.currentThread().getStackTrace()来获得。就点到为止了。这次应该获得调用当前方法的方式的技巧名(有点绕,我信你可看明白),所以具体跟了下。

Thread.currentThread().getStackTrace()返回的是一个StackTraceElement数组,内容为调用函数堆栈java stack trace,并且以读取层级关系保存。由于不记得当时用的之后使用的字段下标,想当然的觉得Android和纯Java的层级应该是一样的。所以直接取下标为2(StackTraceElement[2])当成是调用当前方法的方式。后来调试了下才发觉问题。调用当前方法的方式在Android上函数下标为3,纯Java的变量下标为2。

java stack trace_java 方法调用 trace_stack trace 什么意思

出现这个问题是因为Android的java.lang.Thread.getStackTrace方法实际上是调用了Android的VMStack.getThreadStackTrace(this):

/**
     * Returns an array of {@link StackTraceElement} representing the current thread's stack.
     */
    public StackTraceElement[] getStackTrace() {
        StackTraceElement ste[] = VMStack.getThreadStackTrace(this);
        return ste != null ? ste : EmptyArray.STACK_TRACE_ELEMENT;
    }

java 方法调用 trace_java stack trace_stack trace 什么意思

这里不再往深入里跟进去了(好吧,其实是我和不下来了),贴出调试过程中打印的变量调用堆栈信息,可以扫眼函数的调用层级关系:

JAVA版本:

java 方法调用 trace_stack trace 什么意思_java stack trace

[0]java.lang.Thread.getStackTrace(Thread.java:1518)
[1]com.test.TestDemo.testMethod(TestDemo.java:34)
[2]com.test.TestDemo.testMethod1(TestDemo.java:29)
[3]sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[4]sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
[5]sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[6]java.lang.reflect.Method.invoke(Method.java:597)
[7]org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
[8]org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
[9]org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
[10]org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
[11]org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
[12]org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
[13]org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
[14]org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
[15]org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
[16]org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
[17]org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
[18]org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
[19]org.junit.runners.ParentRunner.run(ParentRunner.java:309)
[20]org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
[21]org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
[22]org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
[23]org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
[24]org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
[25]org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Android版本:

java stack trace_java 方法调用 trace_stack trace 什么意思

[0]dalvik.system.VMStack.getThreadStackTrace(Native Method)
[1]java.lang.Thread.getStackTrace(Thread.java:579)
[2]com.demo.android.annotation.view.EventListener.invokeMethod(EventListener.java:60)
[3]com.demo.android.annotation.view.EventListener.onClick(EventListener.java:52)
[4]android.view.View.performClick(View.java:4475)
[5]android.view.View$PerformClick.run(View.java:18786)
[6]android.os.Handler.handleCallback(Handler.java:730)
[7]android.os.Handler.dispatchMessage(Handler.java:92)
[8]android.os.Looper.loop(Looper.java:137)
[9]android.app.ActivityThread.main(ActivityThread.java:5493)
[10]java.lang.reflect.Method.invokeNative(Native Method)
[11]java.lang.reflect.Method.invoke(Method.java:525)
[12]com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
[13]com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
[14]dalvik.system.NativeStart.main(Native Method)
[0]dalvik.system.VMStack.getThreadStackTrace(Native Method)
[1]java.lang.Thread.getStackTrace(Thread.java:579)
[2]com.demo.android.annotation.view.EventListener.invokeMethod(EventListener.java:60)
[3]com.demo.android.annotation.view.EventListener.onClick(EventListener.java:52)
[4]java.lang.reflect.Method.invokeNative(Native Method)
[5]java.lang.reflect.Method.invoke(Method.java:525)
[6]com.demo.android.annotation.view.EventListener.invokeMethod(EventListener.java:71)
[7]com.demo.android.annotation.view.EventListener.onClick(EventListener.java:52)
[8]android.view.View.performClick(View.java:4475)
[9]android.view.View$PerformClick.run(View.java:18786)
[10]android.os.Handler.handleCallback(Handler.java:730)
[11]android.os.Handler.dispatchMessage(Handler.java:92)
[12]android.os.Looper.loop(Looper.java:137)
[13]android.app.ActivityThread.main(ActivityThread.java:5493)
[14]java.lang.reflect.Method.invokeNative(Native Method)
[15]java.lang.reflect.Method.invoke(Method.java:525)
[16]com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
[17]com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
[18]dalvik.system.NativeStart.main(Native Method)

从打印Android版本的信息发现,所有调用都源自dalvik.system.NativeStart.main(Native Method),有兴趣可以深和下。

写着写着想起当时看一个开源项目的例程打印log的个别时遭遇过这个难题(早干嘛去了java stack trace,再次指责自己的狗屎的脾气!),还提了个issue,只是没人理。。详见和

其实,日志打印工具类的实现都依赖于Thread.currentThread().getStackTrace()来获得相关信息,所以想自己写一个LogUtils,可以参考下。


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/shouji/article-141180-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...