StackTrace简述以及StackTraceElement使用实例

简介: MainActivity如下:package cc.pp;import android.os.Bundle;import android.app.
MainActivity如下:
package cc.pp;

import android.os.Bundle;
import android.app.Activity;
/**
 * Demo描述:
 * StackTrace简述以及StackTraceElement使用实例
 * 
 * 
 * StackTrace简述
 * 1 StackTrace用栈的形式保存了方法的调用信息.
 * 2 怎么获取这些调用信息呢?
 *   可用Thread.currentThread().getStackTrace()方法
 *   得到当前线程的StackTrace信息.
 *   该方法返回的是一个StackTraceElement数组.
 * 3 该StackTraceElement数组就是StackTrace中的内容.
 * 4 遍历该StackTraceElement数组.就可以看到方法间的调用流程.
 *   比如线程中methodA调用了methodB那么methodA先入栈methodB再入栈.
 * 5 在StackTraceElement数组下标为2的元素中保存了当前方法的所属文件名,当前方法所属
 *   的类名,以及该方法的名字.除此以外还可以获取方法调用的行数.
 * 6 在StackTraceElement数组下标为3的元素中保存了当前方法的调用者的信息和它调用
 *   时的代码行数.
 *   
 *   
 * 示例说明:
 * 1 methodA()调用methodB()
 *   methodB()调用methodC()
 * 2 在methodC()中获取StackTrace中的内容并遍历StackTraceElement数组
 *   这样就能观察到从开始到现在的方法间调用流程.
 *   在该流程中可以观察到:
 *   StackTraceElement数组下标为2的元素中保存了当前方法的所属文件名,
 *   当前方法所属的类名,以及该方法的名字.
 *   除此以外还可以利用stackTraceElement.getLineNumber()获取调用getStackTrace()方法的行数.
 *   
 *   在StackTraceElement数组下标为3的元素中保存了当前方法的调用者的信息.
 *   并且可以还可以利用stackTraceElement.getLineNumber()获取到调用时的代码行数.
 *   注意此时获取到的不再是调用getStackTrace()方法的行数.
 * 3 methodC()调用methodD()
 *   在methodD()中获取StackTraceElement数组下标为2和3的元素信息.
 *   这两个元素包含了对于代码调试的重要信息.所以在此单独获取查看.
 */
public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		methodA();
	}
	
	
	private void methodA(){
		System.out.println("------进入methodA----------");
		methodB();
	}
	
	private void methodB(){
		System.out.println("------进入methodB----------");
		methodC();
	}
	
	/**
	 * 遍历StackTrace中的内容并遍历StackTraceElement数组
	 * 请注意观察此处的输出信息.
	 */
	private void methodC(){
		System.out.println("------进入methodC----------");
		StackTraceElement stackTraceElements[]=Thread.currentThread().getStackTrace();
		for (int i = 0; i < stackTraceElements.length; i++) {
			String threadName=Thread.currentThread().getName();
			long threadID=Thread.currentThread().getId();
			StackTraceElement stackTraceElement=stackTraceElements[i];
			String className=stackTraceElement.getClassName();
			String methodName=stackTraceElement.getMethodName();
			String fileName=stackTraceElement.getFileName();
			int lineNumber=stackTraceElement.getLineNumber();
			System.out.println("StackTraceElement数组下标 i="+i+",threadID="+threadID+",threadName="+threadName+",fileName="
			                    +fileName+",className="+className+",methodName="+methodName+",lineNumber="+lineNumber);
			System.out.println("-------------");
		}
		methodD();
	}
	
	/**
	 * 在methodC中遍历StackTraceElement数组.
	 * 但是发现下标为2和3的元素包含的信息是最有用的.
	 * 于是在这里单独获取.
	 */
	private void methodD(){
		System.out.println("------进入methodD----------");
		StackTraceElement stackTraceElement=null;
		String threadName=Thread.currentThread().getName();
		long threadID=Thread.currentThread().getId();
		stackTraceElement=Thread.currentThread().getStackTrace()[2];
		String className=stackTraceElement.getClassName();
		String methodName=stackTraceElement.getMethodName();
		String fileName=stackTraceElement.getFileName();
		int lineNumber=stackTraceElement.getLineNumber();
		System.out.println("该方法的信息:threadID="+threadID+",threadName="+threadName+",fileName="+fileName+
				          ",className="+className+",methodName="+methodName+",lineNumber="+lineNumber);
		stackTraceElement=Thread.currentThread().getStackTrace()[3];
		className=stackTraceElement.getClassName();
		methodName=stackTraceElement.getMethodName();
		fileName=stackTraceElement.getFileName();
		lineNumber=stackTraceElement.getLineNumber();
		System.out.println("该方法的调用者的信息:threadID="+threadID+",threadName="+threadName+",fileName="+fileName+
				          ",className="+className+",methodName="+methodName+",lineNumber="+lineNumber);
	}
	
}

main.xml如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="StackTrace简述以及StackTraceElement使用实例" />

</RelativeLayout>


相关文章
|
分布式计算 Hadoop Scala
阿里云一键部署 Spark 分布式集群
Apache Spark是专为大规模数据处理而设计的快速通用的计算引擎,可以完成各种各样的运算,包括 SQL 查询、文本处理、机器学习等。通过ROS大家可以在阿里云上一键部署Spark集群。
14121 0
|
SQL Java 数据库连接
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
MyBatis-Plus是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。本文讲解了最新版MP的使用教程,包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段等核心功能。
1854 5
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
|
移动开发 安全 Swift
TIOBE 6月榜单:Swift强势挺进,编程语言版图的悄然变革
【6月更文挑战第21天】**TIOBE 6月榜:Swift晋升至第12,凸显其在苹果生态和移动开发中的重要性。自2014年发布以来,Swift凭借强类型、内存安全等特性赢得开发者青睐。排名上升源于苹果支持、开源跨平台、教育普及及性能提升。Swift的崛起影响行业生态,提升开发效率,预示着语言生态、跨平台和教育先行的趋势。未来,Swift有望扩展到更多领域,持续优化并深化教育影响。**
449 6
|
设计模式 Java 测试技术
Spring状态机的实现原理和业务场景
**Spring State Machine**是Spring框架的一部分,它提供了一种实现状态机的方式,允许开发者定义状态机的状态、事件、行为和转换。状态机是一种计算模型,根据一系列规则从一个状态转移到另一个状态。【5月更文挑战第4天】
687 2
|
Android开发
09. 【Android教程】表格布局 TableLayout
09. 【Android教程】表格布局 TableLayout
276 0
|
存储 机器学习/深度学习 算法
如何准确的估计llm推理和微调的内存消耗
最近发布的三个大型语言模型——Command-R+ (104B参数), Mixtral-8x22b (141B参数的MoE模型), 和 Llama 3 70b (70.6B参数)——需要巨大的内存资源。推理时,Command-R+需193.72GB GPU RAM,Mixtral-8x22B需262.63GB,Llama 370b需131.5GB。激活的内存消耗根据序列长度、批大小等因素变化。文章详细介绍了计算这些模型内存需求的方法,并探讨了如何通过量化、优化器优化和梯度检查点减少内存使用,以适应微调和推理。
2170 0
|
缓存 Java 编译器
1.SpringBoot01-自定义注解
1.SpringBoot01-自定义注解
896 0
|
NoSQL 编译器 开发工具
音视频源码调试前准备vs2019+qt5.15.2搭建可调试环境
音视频源码调试前准备vs2019+qt5.15.2搭建可调试环境
455 0
|
机器人
用八爪鱼RPA实现员工薪资管理,轻松拆分发放工资单!
RPA(机器人流程自动化)技术可以极大地压缩、优化现有的员工薪资管理流程。通过使用rpa机器人,可以自动化个税计算和申报,自动化工资单处理和发放等重复性、繁琐的任务。这样可以节省大量人力和时间,提高工作效率,减少错误和延误,提升员工满意度。同时,rpa还可以保证数据的准确性,提高工资管理的合规性,增强企业的信誉。
|
Linux 网络安全
CentOS7网络配置-静态IP设置
CentOS7网络配置-静态IP设置
1488 0