log库的使用

在日常开发中 我们时常会需要打log或者debug来检查代码是否正确,来调试业务逻辑,但是 我们时常会因为修复bug而打很多log 但是事后又要一个一个去删除 不仅麻烦 而且耗时,所以有没有一种可以随时控制log是否输出和方法呢,当然有  

接下来这篇文章就是从这个问题出发所做的关于如何随心打log 和如何快速定位log位置的文章

我们在查看崩溃日志的时候 经常会发现有类似于这样的日志


在我们的日志后面会有错误代码行数提醒  接下来 

我们就要实现这样的功能 让我们的log不仅可以随时控制输出 而且知道我们输出的位置

好了 

首先我们需要实现代码输出控制 ,我们在使用系统控制log输出的基础上封装一层

通过是否需要输出的布尔值来控制日志的输出 下面上代码:

private final static boolean DEBUG = true;
public static void i(String tag,Object o) {
    if (DEBUG) {
        Log.i(TAG, tag+" "+String.valueOf(o));
    }
}
类似于上面代码,我们自己新建一个类 专门用来打印我们自己的日志,在这个类中 我们可以通过 是否是debug模式 来控制是否打印log 我们只需要改变布尔值是true还是false就可以达到目的 ,好 现在日志的打印已经实现了随心控制  那么接下来 我们来实现如何在日志后面加上我们的代码位置行数

这里我们主要用到StackTraceElement这个类

先在这里放一下效果:


当我们打印这个log的时候 会在后面加上我们的代码位置 这样不仅便于找bug  同时 方便bug修复后删除日志

而实现这个 主要用到的类就是StackTraceElement,怎么用呢

客官请看:

StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();

通过当前线程拿到当前线程的栈帧集合,

这个可以理解为当我们调用方法的时候,每进入一个方法,会将该方法的相关信息(例如:类名,方法名,方法调用行数等)存储下来,压入到一个栈中,当方法返回的时候再将其出栈。


在这个集合里面我们有许许多多的信息 而我们需要的只是当前这个log类的信息 所有 我们要将信息筛选出来 那么怎么筛选呢

StackTraceElement给我们提供了四个主要的方法

分别为:

获取类名 ,获取文件名 获取方法名 获取所在行

那么问题就简单了 

我们可以根据我们当前的这个log类名来筛选我们的信息

private static StackTraceElement getTargetStackTraceElement() {
    // find the target invoked method
    StackTraceElement targetStackTrace = null;
    boolean shouldTrace = false;
    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
    for (StackTraceElement stackTraceElement : stackTrace) {
        boolean isLogMethod = stackTraceElement.getClassName().equals(HBLog.class.getName());
        if (shouldTrace && !isLogMethod) {
            targetStackTrace = stackTraceElement;
            break;
        }
        shouldTrace = isLogMethod;
    }
    return targetStackTrace;
}
HBlog是我的类的名字 大家要用直接改成自己当前的类的名字就可以了。

好 接下来只需要调用就可以了:

public static void i(String tag,Object o) {
    if (DEBUG) {
        StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
        Log.i(TAG, tag+" "+String.valueOf(o)+ "(" + targetStackTraceElement.getFileName() + ":"
                + targetStackTraceElement.getLineNumber() + ")");
    }
}
就这样 只要在代码中调用这个方法 就会把相对应的文件名字 所在行数打印出来


贴下我的这个类的代码:

public class HBLog {
    private final static boolean DEBUG = true;
    private static final String TAG = "hb";

    public static boolean isLogEnable(){
        return DEBUG;
    }



    public static void i(String tag,Object o) {
        if (DEBUG) {
            StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
            Log.i(TAG, tag+" "+String.valueOf(o)+ "(" + targetStackTraceElement.getFileName() + ":"
                    + targetStackTraceElement.getLineNumber() + ")");
        }
    }

    public static void i(Object o) {
        if (DEBUG) {
            StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
            Log.i(TAG, String.valueOf(o)+"(" + targetStackTraceElement.getFileName() + ":"
                    + targetStackTraceElement.getLineNumber() + ")");
        }
    }

    private static StackTraceElement getTargetStackTraceElement() {
        // find the target invoked method
        StackTraceElement targetStackTrace = null;
        boolean shouldTrace = false;
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        for (StackTraceElement stackTraceElement : stackTrace) {
            boolean isLogMethod = stackTraceElement.getClassName().equals(HBLog.class.getName());
            if (shouldTrace && !isLogMethod) {
                targetStackTrace = stackTraceElement;
                break;
            }
            shouldTrace = isLogMethod;
        }
        return targetStackTrace;
    }

    public static void d(String tag,Object o) {
        if (DEBUG) {
            StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
            Log.d(TAG, tag+" "+String.valueOf(o)+"(" + targetStackTraceElement.getFileName() + ":"
                    + targetStackTraceElement.getLineNumber() + ")");
        }
    }

    public static void d(Object o) {
        if (DEBUG) {
            StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
            Log.i(TAG, String.valueOf(o)+"(" + targetStackTraceElement.getFileName() + ":"
                    + targetStackTraceElement.getLineNumber() + ")");
        }
    }

    public static void e(String tag,Object o) {
        if (DEBUG) {
            StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
            Log.e(TAG, tag+" "+String.valueOf(o)+"(" + targetStackTraceElement.getFileName() + ":"
                    + targetStackTraceElement.getLineNumber() + ")");
        }
    }

    public static void e(Object o) {
        StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
        Log.e(TAG, String.valueOf(o)+"(" + targetStackTraceElement.getFileName() + ":"
                + targetStackTraceElement.getLineNumber() + ")");
    }

    public static void e(Object o,Throwable t) {
        t.printStackTrace();
        StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
        Log.e(TAG, String.valueOf(o) + " error:" + t.getMessage()+"(" + targetStackTraceElement.getFileName() + ":"
                + targetStackTraceElement.getLineNumber() + ")");
    }

    public static void w(Object o) {
        if (DEBUG) {
            StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
            Log.w(TAG, String.valueOf(o)+"(" + targetStackTraceElement.getFileName() + ":"
                    + targetStackTraceElement.getLineNumber() + ")");
        }
    }

    public static void w(String tag,Object o) {
        if (DEBUG) {
            StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
            Log.w(TAG, tag+" "+String.valueOf(o)+"(" + targetStackTraceElement.getFileName() + ":"
                    + targetStackTraceElement.getLineNumber() + ")");
        }
    }

//    public static void w(Object o,Throwable t) {
//        if (DEBUG) {
//            t.printStackTrace();
//            Log.w(TAG, String.valueOf(o) + " error:" + t.getMessage());
//        }
//    }


    public static void v(Object o) {
        if (DEBUG) {
            StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
            Log.v(TAG, String.valueOf(o)+"(" + targetStackTraceElement.getFileName() + ":"
                    + targetStackTraceElement.getLineNumber() + ")");
        }
    }

    public static void v(String tag,Object o) {
        if (DEBUG) {
            StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
            Log.v(TAG, tag+" "+String.valueOf(o)+"(" + targetStackTraceElement.getFileName() + ":"
                    + targetStackTraceElement.getLineNumber() + ")");
        }
    }

    public static void d(Object... os) {
        if (DEBUG) {
            StringBuilder stringBuilder = new StringBuilder();
            for (Object o: os) {
                stringBuilder.append(String.valueOf(o)).append(" ");
            }
            Log.d(TAG, stringBuilder.toString());
        }
    }
}


当然 log还有很多花样可以玩 不过这不是这篇文章的重点,样式如下 盗图一张:

网址如下:

里面各种各样的都有 

好了 就介绍到这里 希望各位大神不吝赐教。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值