Skip to content

StackOffset

Muyangmin edited this page Sep 8, 2016 · 1 revision

**栈帧偏移(StackOffset)**是PLog的一个重要概念和特性。

什么是栈帧偏移

PLog通过获取当前线程的StackTrace的方式来读取调用日志的位置信息。下面是一个典型的StackTrace:

dalvik.system.VMStack.getThreadStackTrace(Native Method)
java.lang.Thread.getStackTrace(Thread.java:580)
org.mym.plog.PLog.getLineNumAndMethodName(PLog.java:385)
org.mym.plog.PLog.wrapLogStr(PLog.java:349)
org.mym.plog.PLog.log(PLog.java:218)
org.mym.plog.PLog.v(PLog.java:113)
org.mym.prettylog.MainActivity.basicUsage(MainActivity.java:53)
org.mym.prettylog.MainActivity_ViewBinding$1.doClick(MainActivity_ViewBinding.java:52)
butterknife.internal.DebouncingOnClickListener.onClick(DebouncingOnClickListener.java:22)
android.view.View.performClick(View.java:4781)
android.view.View$PerformClick.run(View.java:19874)
android.os.Handler.handleCallback(Handler.java:739)
android.os.Handler.dispatchMessage(Handler.java:95)
android.os.Looper.loop(Looper.java:135)
android.app.ActivityThread.main(ActivityThread.java:5446)
java.lang.reflect.Method.invoke(Native Method)
java.lang.reflect.Method.invoke(Method.java:372)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:941)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:736)

可以看出,开始和末尾的的几个StackTraceElement都是系统和线程相关的方法,与应用相关性不大。而PLog的KeepLineNumberuseAutoTag的功能,目标是要找到真正的调用日志那一行。
在上面的StackTrace中,我们关心的是basicUsage(MainActivity.java:53),在这一行应用调用了PLog.v()方法。这个StackTraceElement在数组中的位置为6,这个数字就被称为StackOffset

自定义全局偏移

考虑以下两种应用场景:

在上述场景下,按照前一节的办法预定义的栈帧偏移将定位到非预期的位置,因此PLog提供了全局偏移的设置,即globalStackOffset

Tips:

  1. globalStackOffset与预定义的offset是叠加的关系,因此你只需要计算你对PLog的方法做了多少层封装
  2. 如果使用标准实现的wrapper class,只需要将这个偏移量设置为2即可。

为单个日志指定栈帧偏移

一般不推荐这种做法;如果确实有这样的需求,请使用logWithStackOffset(int level, int stackOffset, String tag, String msg, Object... params)方法。