安卓工具类LogUtils二次封装

目录

 

 

目标

1封装

2增加日志信息


 

目标

1.对Log类做一个封装,取消tag参数,只保留msg信息

2.输出当前日志输出位置所在的类,方法和代码行号

1封装

从最简单的一步开始,对log.d()进行封装

public class LoggerUtils {

    public static void d(String msg){
        String clazz="className";
        String method="methodName";
        String line="lineNum";
        StringBuilder sb=new StringBuilder();
        sb.append(clazz)
                .append(".")
                .append(method)
                .append(line);
        Log.d(sb.toString(), msg);
    }
}

2增加日志信息

在AS中,有调试工具,可以方便我们打断点,运行程序并查看断点位置的方法和值.这实际上是因为java虚拟机,会随时保存运行调用的方法和变量值到堆栈中,打断点的作用,相当于方便的插入了一个日志输出点

现在用代码来实现

参考并学习这里  浅谈getStackTrace()方法(一)

在java中运行代码

/**
 * 用来测试堆栈信息
 */
public class StackTest {


    private static void test(){
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
        System.out.println("The stackTraceElements length:" + stackTraceElements.length);
        for (int i = 0; i < stackTraceElements.length; i++) {
            System.out.println("\n---the  " + i + "  element" + "---");
            System.out.println("toString:" + stackTraceElements[i].toString());
            System.out.println("ClassName:" + stackTraceElements[i].getClassName());
            System.out.println("FileName:" + stackTraceElements[i].getFileName());
            System.out.println("LineNumber:" + stackTraceElements[i].getLineNumber());
            System.out.println("MethodName:" + stackTraceElements[i].getMethodName());
        }
    }

    public static void main(String[] args) {
       test();
    }

}

获得以下输出

The stackTraceElements length:3

---the  0  element---
toString:java.base/java.lang.Thread.getStackTrace(Thread.java:1606)
ClassName:java.lang.Thread
FileName:Thread.java
LineNumber:1606
MethodName:getStackTrace

---the  1  element---
toString:com.npt.stack_test.StackTest.test(StackTest.java:10)
ClassName:com.npt.stack_test.StackTest
FileName:StackTest.java
LineNumber:10
MethodName:test

---the  2  element---
toString:com.npt.stack_test.StackTest.main(StackTest.java:23)
ClassName:com.npt.stack_test.StackTest
FileName:StackTest.java
LineNumber:23
MethodName:main

Process finished with exit code 0

可以发现在stackTraceElements中,第一个方法必然是getStackTrace(),然后按照调用顺序,依次是test(),main()

stackTraceElements中还保存了调用方法所属的类名,以及在文件中的第几行的行号

在安卓应用中运行上面的代码

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        test();
    }

    private void test() {
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
        System.out.println("The stackTraceElements length:" + stackTraceElements.length);
        for (int i = 0; i < stackTraceElements.length; i++) {
            System.out.println("\n---the  " + i + "  element" + "---");
            System.out.println("toString:" + stackTraceElements[i].toString());
            System.out.println("ClassName:" + stackTraceElements[i].getClassName());
            System.out.println("FileName:" + stackTraceElements[i].getFileName());
            System.out.println("LineNumber:" + stackTraceElements[i].getLineNumber());
            System.out.println("MethodName:" + stackTraceElements[i].getMethodName());
        }
    }
}

查看logcat输出

System.out: The stackTraceElements length:17
System.out: ---the  0  element---
System.out: toString:dalvik.system.VMStack.getThreadStackTrace(Native Method)
System.out: ClassName:dalvik.system.VMStack
System.out: FileName:VMStack.java
System.out: LineNumber:-2
System.out: MethodName:getThreadStackTrace
System.out: ---the  1  element---
System.out: toString:java.lang.Thread.getStackTrace(Thread.java:580)
System.out: ClassName:java.lang.Thread
System.out: FileName:Thread.java
System.out: LineNumber:580
System.out: MethodName:getStackTrace
System.out: ---the  2  element---
System.out: toString:com.npt.testdemo.MainActivity.test(MainActivity.java:17)
System.out: ClassName:com.npt.testdemo.MainActivity
System.out: FileName:MainActivity.java
System.out: LineNumber:17
System.out: MethodName:test
System.out: ---the  3  element---
System.out: toString:com.npt.testdemo.MainActivity.onCreate(MainActivity.java:13)
System.out: ClassName:com.npt.testdemo.MainActivity
System.out: FileName:MainActivity.java
System.out: LineNumber:13
System.out: MethodName:onCreate
System.out: ---the  4  element---
System.out: toString:android.app.Activity.performCreate(Activity.java:6033)
System.out: ClassName:android.app.Activity
System.out: FileName:Activity.java
System.out: LineNumber:6033
System.out: MethodName:performCreate
System.out: ---the  5  element---
System.out: toString:android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
System.out: ClassName:android.app.Instrumentation
System.out: FileName:Instrumentation.java
System.out: LineNumber:1106
System.out: MethodName:callActivityOnCreate
System.out: ---the  6  element---
System.out: toString:android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
System.out: ClassName:android.app.ActivityThread
System.out: FileName:ActivityThread.java
System.out: LineNumber:2278
System.out: MethodName:performLaunchActivity
System.out: ---the  7  element---
System.out: toString:android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
System.out: ClassName:android.app.ActivityThread
System.out: FileName:ActivityThread.java
System.out: LineNumber:2387
System.out: MethodName:handleLaunchActivity
System.out: ---the  8  element---
System.out: toString:android.app.ActivityThread.access$800(ActivityThread.java:151)
System.out: ClassName:android.app.ActivityThread
System.out: FileName:ActivityThread.java
System.out: LineNumber:151
System.out: MethodName:access$800
System.out: ---the  9  element---
System.out: toString:android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
System.out: ClassName:android.app.ActivityThread$H
System.out: FileName:ActivityThread.java
System.out: LineNumber:1303
System.out: MethodName:handleMessage
System.out: ---the  10  element---
System.out: toString:android.os.Handler.dispatchMessage(Handler.java:102)
System.out: ClassName:android.os.Handler
System.out: FileName:Handler.java
System.out: LineNumber:102
System.out: MethodName:dispatchMessage
System.out: ---the  11  element---
System.out: toString:android.os.Looper.loop(Looper.java:135)
System.out: ClassName:android.os.Looper
System.out: FileName:Looper.java
System.out: LineNumber:135
System.out: MethodName:loop
System.out: ---the  12  element---
System.out: toString:android.app.ActivityThread.main(ActivityThread.java:5254)
System.out: ClassName:android.app.ActivityThread
System.out: FileName:ActivityThread.java
System.out: LineNumber:5254
System.out: MethodName:main
System.out: ---the  13  element---
System.out: toString:java.lang.reflect.Method.invoke(Native Method)
System.out: ClassName:java.lang.reflect.Method
System.out: FileName:Method.java
System.out: LineNumber:-2
System.out: MethodName:invoke
System.out: ---the  14  element---
System.out: toString:java.lang.reflect.Method.invoke(Method.java:372)
System.out: ClassName:java.lang.reflect.Method
System.out: FileName:Method.java
System.out: LineNumber:372
System.out: MethodName:invoke
System.out: ---the  15  element---
System.out: toString:com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:902)
System.out: ClassName:com.android.internal.os.ZygoteInit$MethodAndArgsCaller
System.out: FileName:ZygoteInit.java
System.out: LineNumber:902
System.out: MethodName:run
System.out: ---the  16  element---
System.out: toString:com.android.internal.os.ZygoteInit.main(ZygoteInit.java:697)
System.out: ClassName:com.android.internal.os.ZygoteInit
System.out: FileName:ZygoteInit.java
System.out: LineNumber:697
System.out: MethodName:main

可以看到安卓activity的调用是要经过非常多的步骤的.这里暂时打住,只关注我们的代码,test()

可以看到,与java类似,在stackTrace中,首先保存的是getStackTrace本身,不过由于android的虚拟机dalvik是对java虚拟机的优化,getStackTrace()方法实际上是还要调用getThreadStackTrace(Native Method),一个本地方法

test()方法在第三个,而test()所在的方法在第四个,onCreate(),行号13与我本地位置也对的上

那么在这里就可以继续对封装优化

public class LoggerUtils {

    public static void d(String msg){
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
        //获取日志所在方法的类
        String clazz=stackTraceElements[3].getClassName();
        //如果有一连串包名,只包留最后一个类名
        String[] path=clazz.split("\\.");
        if (path.length>0){
            clazz=path[path.length-1];
        }
        //获取日志类所在的方法名
        String method=stackTraceElements[3].getMethodName();
        //获取日志在调用类中的代码行数
        int line=stackTraceElements[3].getLineNumber();
        //按照  [类名].[方法名](line:[行数])的格式拼接日志信息头
        String sb = clazz +
                "." +
                method +
                "(line:" +
                line +
                ")";
        //输出信息头+日志
        Log.d(sb, msg);
    }
}

然后尝试下应用

 

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        LoggerUtils.d("Hello World!");
    }

}

如愿以偿的看到输出

MainActivity.onCreate(line:13): Hello World!

git线上地址

https://gitee.com/cross_time/android-tools.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值