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>


相关文章
|
4月前
|
缓存
KVCache原理简述
KVCache原理简述
44 0
|
10月前
|
设计模式 监控 Java
Java 代理模式的基本概念、使用场景、应用示例和实现方法
Java 代理模式的基本概念、使用场景、应用示例和实现方法
138 0
|
10月前
|
数据库 索引
简述创建索引的注意事项
创建索引是提高数据库查询性能的重要手段之一,合理地创建索引可以加快查询速度,提升数据库的整体性能。以下是创建索引时需要注意的几个重要事项:
216 0
|
11月前
|
安全 Java 测试技术
工作中单例模式用法及其使用场景?
工作中单例模式用法及其使用场景?
73 0
|
开发框架 PHP
PHPfinal方法的使用场景是什么?底层原理是什么?
PHPfinal方法的使用场景是什么?底层原理是什么?
|
设计模式 算法 程序员
java-23种设计模式概述【软件设计模式基本介绍(是什么、作用、优点)、模式的分类和介绍】
java-23种设计模式概述【软件设计模式基本介绍(是什么、作用、优点)、模式的分类和介绍】
235 0
|
Java API 调度
java多线程之概念和3种创建方式(详解)
进程:一个执行的应用程序 线程:一个应用程序内的具体执行不同模块
103 0
java多线程之概念和3种创建方式(详解)
简述for in 和 for of 的区别
1、推荐在循环对象属性的时候使用 for...in,在遍历数组的时候的时候使用 for...of 2、for...in 循环出的是 key,for...of 循环出的是 value
121 0
简述for in 和 for of 的区别
|
Scala 开发者
包对象注意事项和细节说明|学习笔记
快速学习包对象注意事项和细节说明。
50 0
包对象注意事项和细节说明|学习笔记
个人简述
以下是我的个人简述