Android查看调用函数名与行号等信息的日志类

Android查看调用函数名与行号等信息的日志类

用C的人一定知道__FILE__、__func__和__LINE__,可以方便的跟踪代码执行到哪个文件里面的那个函数,是第多少行,但是Java中并没有这样的定义,在调试代码时会感觉到很不方便。但是,我们也可以通过一些函数来实现同样的功能。

参考网络上的一些文章,我整理实现了一个日志类,实现如下目标:

  1. 能实现调试跟踪功能;
  2. 能打印出类名、方法名、行号;
  3. 能在发布时很容易的关闭日志;
  4. 简化在书写代码时添加日志的操作:
    a. 在只需要跟踪运行位置时,能简单的拷贝复制;
    b. 需要增加描述时,方便添加;
  5. 在查看日志时,能方便的挑选自己感兴趣的日志。

下面我来根据前面定下的目标,逐项来说明如何实现,在文章的最后附上代码。

1,能实现调试跟踪功能;

这个功能,系统提供的android.util.Log就很好的实现了,在我们的类中直接使用,只是再加一层接口封装。

2,能打印出类名、方法名、行号;

打印调用栈是android平台问题定位的基本方法,如果需要知道谁在调用某个函数,可以在此函数中添加打印调用栈函数,弄清楚函数之间的调用关系。我们可以通过查看调用栈来获取类名,方法名,行号等。
Exception e = new Exception();
StackTraceElement[] trace = e.getStackTrace();
获取类名:trace[0].getClassName()
获取方法名:trace[0].getMethodName()
获取行号:trace[0].getLineNumber()

3,能在发布时很容易的关闭日志;

定义一个Log的LEVEL,在每次调用 android.util.Log 之前,先判断LEVEL是否在范围内,若不在,则不输出日志。这样,在平常需要调试时,设置我们的输出级别,在发布时,可以控制不输出日志。只需要修改一处代码即可实现功能。
所有日志级别都输出:
public static final int LEVEL = VERBOSE;
发布时,所有日志都不输出:
public static final int LEVEL = NOTHING;

4,简化在书写代码时添加日志的操作:

a,在只需要跟踪运行位置时,能简单的复制粘贴;
b,需要增加描述时,方便添加;

根据平时添加的习惯,日志的TAG参数,使用类名,在日志的内容里面,添加方法名,以及行号,有了这些信息,就可以很好的确认打印位置了。我实现出来后,在要添加日志的地方就是一句:
LogUtil.logWithMethod(new Exception());
所以,在不需要添加附加信息时,例如,记录某个地方是否执行到,只需要简单的拷贝一份就行了。
考虑到还是有很多地方需要添加消息内容的,就在类里面使用同名函数的重载,后面添加一个String参数。这样,保持了书写习惯上的相似性。示例如下:
LogUtil.logWithMethod(new Exception(),”task id is ” + getTaskId());

5,在查看日志时,能方便的挑选自己感兴趣的日志;

为了方便选择日志,在写消息内容时,添加了一个固定信息:“LogUtil”,当然,也可以修改为其他内容,这个信息就是用于进行日志内容过滤的。对于一个较大的工程,不一定是一个人开发的,那么,不同的人可以使用不同的过滤特征字。而且系统还会有许多其他的日志信息,使用这个我们添加的特征字来过滤,就可以只查看我们关心的内容了。另外,类名,方法名,都可以做为过滤器来使用。
输出信息示例如下:
06-10 08:39:48.278: I/MainActivity(2581): logUtil: onCreate:21
06-10 08:39:48.278: I/MainActivity(2581): logUtil: onCreate:22: task id is 26
其中,简单类名“MainActivity”可以用作TAG过滤,而内容特征字“logUtil”以及函数名“onCreate”都可以用作内容过滤。

该日志类的实现代码具体如下:

package com.example.logutil;

import java.util.StringTokenizer;
import android.util.Log;

/**
* The Class LogUtil for log printing, which help us 
* easy to trace our codes or logics in the project . 
* @author lintax  
* @time 2016.6.10 
*/ 

public class LogUtil {

    public static final int VERBOSE = 1;
    public static final int DEBUG = 2;
    public static final int INFO = 3;
    public static final int WARN = 4;
    public static final int ERROR = 5;
    public static final int NOTHING = 6;

    private static final int LEVEL = VERBOSE;// control the output info level
    private static final String logContentFilter = "logUtil";

    public static void v(String tag, String msg) {
        if (LEVEL <= VERBOSE) {
            Log.v(tag, msg);
        }
    }

    public static void d(String tag, String msg) {
        if (LEVEL <= DEBUG) {
            Log.d(tag, msg);
        }
    }

    public static void i(String tag, String msg) {
        if (LEVEL <= INFO) {
            Log.i(tag, msg);
        }
    }

    public static void w(String tag, String msg) {
        if (LEVEL <= WARN) {
            Log.w(tag, msg);
        }
    }

    public static void e(String tag, String msg) {
        if (LEVEL <= ERROR) {
            Log.e(tag, msg);
        }
    }

    public static void logWithMethod(Exception e) {
        StackTraceElement[] trace = e.getStackTrace();
        if (trace == null || trace.length == 0) {
            i("error", "log: get trace info failed");
        }
        String class_name = getSimpleClassName(trace[0].getClassName());
        i(class_name, logContentFilter + ": " + trace[0].getMethodName() 
                + ":" + trace[0].getLineNumber());
    }

    public static void logWithMethod(Exception e, String msg) {
        StackTraceElement[] trace = e.getStackTrace();
        if (trace == null || trace.length == 0) {
            i("error", "log: get trace info failed");
        }
        String class_name = getSimpleClassName(trace[0].getClassName());
        i(class_name, logContentFilter + ": " + trace[0].getMethodName() 
                + ":" + trace[0].getLineNumber() + ": " + msg);
    }

    public static String getSimpleClassName(String fullClassName) {
        String split = ".";
        String class_name = "";
        StringTokenizer token = new StringTokenizer(fullClassName, split);
        while (token.hasMoreTokens()) {
            class_name = token.nextToken();
        }
        return class_name;
    }

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值