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

来源:互联网 发布:intro.js 编辑:程序博客网 时间:2024/05/22 12:19

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

1.引入Java的线程运行栈

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

观察输出结果可以看出栈中先执行的方法是VM和Thread中的方法。第3条才是你调用所在的方法(调用getStackTrack的方法)。

2.日志模块设计

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