你通常如何标记日志条目? (机器人)
我假设大部分人都知道android.util.Log所有的日志logging方法都接受'String tag'作为第一个参数。
而我的问题是, 你如何通常在你的应用程序中标记你的日志? 我已经看到了这样的硬编码:
public class MyActivity extends Activity { private static final String TAG = "MyActivity"; //... public void method () { //... Log.d(TAG, "Some logging"); } }
这看起来不太好,原因很多:
- 你可以告诉我这个代码没有硬编码,但它确实。
- 我的应用程序可以有不同包中具有相同名称的任何数量的类。 所以这将是很难读取日志。
- 这不灵活。 你总是把一个私人领域的标签放入你的class级。
有没有什么好办法让一个class的TAG?
我使用一个TAG,但是我像这样初始化它:
private static final String TAG = MyActivity.class.getName();
这样当我重构我的代码时,标签也会相应地改变。
我通常创build一个App
类,它位于不同的包中,并包含有用的静态方法。 其中一个方法是一个getTag()
方法,这样我就可以在任何地方获得TAG。
App
类看起来像这样:
编辑 :改进每br怪物评论(谢谢:))
public class App { public static String getTag() { String tag = ""; final StackTraceElement[] ste = Thread.currentThread().getStackTrace(); for (int i = 0; i < ste.length; i++) { if (ste[i].getMethodName().equals("getTag")) { tag = "("+ste[i + 1].getFileName() + ":" + ste[i + 1].getLineNumber()+")"; } } return tag; } }
而当我想要使用它时:
Log.i(App.getTag(), "Your message here");
getTag
方法的输出是调用者类的名称(带有包名称)以及调用getTag
的行号,以便于debugging。
我喜欢提高Yaniv答案,如果你有这种格式的日志(filename.java:XX)xx行号你可以链接快捷方式相同的方式得到链接,当有一个错误,这样我可以直接到有问题的线路只需点击logcat
我把它放在我的扩展应用程序,所以我可以在任何其他文件中使用
public static String getTag() { String tag = ""; final StackTraceElement[] ste = Thread.currentThread().getStackTrace(); for (int i = 0; i < ste.length; i++) { if (ste[i].getMethodName().equals("getTag")) { tag = "("+ste[i + 1].getFileName() + ":" + ste[i + 1].getLineNumber()+")"; } } return tag; }
截图:
转到Android Studio – >首选项 – >实时模板 – > AndroidLog然后selectLog.d(TAG,String) 。
在模板文本中replace
android.util.Log.d(TAG, "$METHOD_NAME$: $content$");
同
android.util.Log.d("$className$", "$METHOD_NAME$: $content$");
然后单击编辑variables,并在className Name列旁边的Expression列中inputclassName()。
现在,当你input快捷方式logd
它会放
Log.d("CurrentClassName", "currentMethodName: ");
你不需要定义一个TAG了。
当我在方法之间移动代码或重命名方法时,需要更新这些string,我喜欢这样做。 在哲学上,保持标签中的“位置”或“上下文”似乎更好,而不是消息。
public class MyClass { // note this is ALWAYS private...subclasses should define their own private static final LOG_TAG = MyClass.class.getName(); public void f() { Log.i(LOG_TAG + ".f", "Merry Christmas!"); } }
这样做的好处是,即使内容不是静态的,也可以过滤出单个方法,例如
Log.i(LOG_TAG + ".f", String.valueOf(new Random().nextInt()));
唯一的缺点是,当我将f()
重命名为g()
我需要牢记这个string。 此外,自动IDE重构将不会捕获这些。
有一段时间我是使用短类名的粉丝,我的意思是LOG_TAG = MyClass.class.getSimpleName()
。 我发现他们更难过滤日志,因为有更less的事情继续下去。
您可以使用this.toString()
获取您在其中打印到日志的特定类的唯一标识符。
我创build了一类名为S
的静态variables,方法和类。
以下是日志logging方法:
public static void L(Context ctx, Object s) { Log.d("CCC " + ctx.getClass().getName().replace(ctx.getPackageName(), ""), s.toString()); }
它被称为SL(this, whaterver_object);
getClass().getName()
也附加了包名,因此,我将其删除,以避免使标记不必要的太长。
优点:
- 比
Log.d(TAG,
- 不需要将int值转换为string。 事实上不需要input
toString
- 不会忘记删除
Log.d
,因为我只需删除该方法,所有日志的位置将被标记为红色。 - 无需在活动顶部定义TAG,因为它需要类的名称。
- 标签有一个
CCC
的前缀(一个简短的stringtypes),这样很容易在Android Studio的Android监视器中列出你的日志。 有时你正在同时运行服务或其他类。 如果您必须单独按活动名称进行search,则无法准确查看获取服务响应的时间,然后发生活动。 像CCC这样的前缀是有帮助的,因为它可以按照时间顺序logging它所发生的活动
AndroidStudio默认有一个logt
模板(你可以inputlogt
,然后按tab使其扩展为一个代码)。 我build议使用这个来避免粘贴另一个类的TAG定义,并忘记改变你所指的类。 该模板默认扩展为
private static final String TAG = "$CLASS_NAME$"
为了避免重构后使用旧的类名,你可以改变它
private static final String TAG = $CLASS_NAME$.class.getSimpleName();
请记住检查“编辑variables”button,并确保CLASS_NAME
variables被定义为使用className()
expression式,并选中“如果定义跳过”。
我通常使用方法名称作为标签,但从线程
String TAG = Thread.currentThread().getStackTrace()[1].getMethodName();
这避免了新的例外。
private static final String TAG = new RuntimeException().getStackTrace()[0].getClassName();