利用线程运行栈StackTraceElement设计Android日志模块

本文介绍如何在Android应用中利用Java的StackTraceElement自动打印出类名、方法名及行号等详细信息,以便于调试。文章提供了一种通过分析线程调用栈来生成带有位置信息的日志的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果你想在你的Android程序中自动打印MainActivity.onCreate(line:37)这种类名.方法名(行数)的日志该如何实现呢?

1.引入Java的线程运行栈

Java.lang包中提供了StackTraceElement,可以用来获取方法的调用栈信息。通过调用线程函数Thread.currentThread().getStackTrace()可以获得StackTraceElement[]的堆栈数组,数组中保存了线程中的执行调用的方法。观察下面的代码:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Override
   protected void onCreate(Bundle savedInstanceState) {
       super .onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
       System.out.println( "call oncreate method" );
       System.out.println( "stacktrace len:" + stacktrace.length);
       for ( int i = 0 ; i < stacktrace.length; i++) {
           System.out.println( "----  the " + i + " element  ----" );
           System.out.println( "toString: " + stacktrace[i].toString());
           System.out.println( "ClassName: " + stacktrace[i].getClassName());
           System.out.println( "FileName: " + stacktrace[i].getFileName());
           System.out.println( "LineNumber: " + stacktrace[i].getLineNumber());
           System.out.println( "MethodName: " + stacktrace[i].getMethodName());
       }
   }
在onCreate方法中调用getStackTrace方法获取调用栈的信息。打印的结果如下:  \
观察输出结果可以看出栈中先执行的方法是VM和Thread中的方法。第3条才是你调用所在的方法(调用getStackTrack的方法)。 

2.日志模块设计

生成tag:
?
1
2
3
4
5
6
7
8
private static String generateTag(StackTraceElement stack){
         String tag = "%s.%s(L:%d)" ;
         String className = stack.getClassName();
         className = className.substring(className.lastIndexOf( "." )+ 1 );
         tag = String.format(tag, stack.getClassName(),className,stack.getLineNumber());
         tag = customTagPrefix== null ?tag:customTagPrefix+ ":" +tag;
         return tag;
     }
CustomTagPrefix是自定义的前缀。 包装LOG:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void d(String content){
         if (!allowD) {
             return ;
         }
         StackTraceElement caller = Thread.currentThread().getStackTrace()[ 3 ];
         String tag = generateTag(caller);
         Log.d(tag, content);
     }
     
     public static void d(String content,Throwable thr){
         if (!allowD) {
             return ;
         }
         StackTraceElement caller = Thread.currentThread().getStackTrace()[ 3 ];
         String tag = generateTag(caller);
         Log.d(tag, content,thr);
     }
getStackTrace()[3],取第四个的原因是前两个分别为vm和Thread的方法,下标2是当前的d()方法,调用d()的方法的下标为3。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值