当前位置: 首页 > news >正文

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

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

1.引入Java的线程运行栈

Java.lang包中提供了StackTraceElement,可以用来获取方法的调用栈信息。通过调用线程函数Thread.currentThread().getStackTrace()可以获得StackTraceElement[]的堆栈数组,数组中保存了线程中的执行调用的方法。观察下面的代码:

@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:

  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:

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。 

相关文章:

  • .Net中ListT 泛型转成DataTable、DataSet
  • linux线程的实现【转】
  • JAVA设计模式
  • 你知道市面上机器人都用哪些操作系统吗【转】
  • ArcGIS安装错误1402
  • 前端的学习
  • .NET 表达式计算:Expression Evaluator
  • 2016-11-10试题解题报告
  • Java中的Random()函数
  • SSD硬盘的4K对齐
  • 《深入理解Java7核心技术与最佳实践》读书笔记(1.1)---Project Coin介绍
  • 关闭CENTOS不必要的默认服务
  • 改变的六条规则
  • ThinkPAD e450 安装 win 7 系统 BIOS设置
  • storm togolopy转换jstorm topology
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • Consul Config 使用Git做版本控制的实现
  • create-react-app项目添加less配置
  • Hibernate最全面试题
  • iOS | NSProxy
  • Laravel Mix运行时关于es2015报错解决方案
  • Logstash 参考指南(目录)
  • QQ浏览器x5内核的兼容性问题
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • Vue ES6 Jade Scss Webpack Gulp
  • Webpack 4x 之路 ( 四 )
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 从0到1:PostCSS 插件开发最佳实践
  • - 概述 - 《设计模式(极简c++版)》
  • 基于axios的vue插件,让http请求更简单
  • 简单数学运算程序(不定期更新)
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 山寨一个 Promise
  • 听说你叫Java(二)–Servlet请求
  • 微信小程序--------语音识别(前端自己也能玩)
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • - 转 Ext2.0 form使用实例
  • 说说我为什么看好Spring Cloud Alibaba
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • (14)目标检测_SSD训练代码基于pytorch搭建代码
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (动态规划)5. 最长回文子串 java解决
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (十七)devops持续集成开发——使用jenkins流水线pipeline方式发布一个微服务项目
  • (图)IntelliTrace Tools 跟踪云端程序
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .net 8 发布了,试下微软最近强推的MAUI
  • .net6Api后台+uniapp导出Excel
  • .NET6使用MiniExcel根据数据源横向导出头部标题及数据
  • .Net程序帮助文档制作
  • @SuppressLint(NewApi)和@TargetApi()的区别
  • [2024] 十大免费电脑数据恢复软件——轻松恢复电脑上已删除文件
  • [Android] Android ActivityManager