你通常如何标记日志条目? (机器人)

我假设大部分人都知道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?

我使用一个TA​​G,但是我像这样初始化它:

 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$");

Android菜单的图像

然后单击编辑variables,并在className Name列旁边的Expression列中inputclassName()。 Android菜单的图像2

现在,当你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()也附加了包名,因此,我将其删除,以避免使标记不必要的太长。

优点:

  1. Log.d(TAG,
  2. 不需要将int值转换为string。 事实上不需要inputtoString
  3. 不会忘记删除Log.d ,因为我只需删除该方法,所有日志的位置将被标记为红色。
  4. 无需在活动顶部定义TAG,因为它需要类的名称。
  5. 标签有一个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_NAMEvariables被定义为使用className()expression式,并选中“如果定义跳过”。

我通常使用方法名称作为标签,但从线程

 String TAG = Thread.currentThread().getStackTrace()[1].getMethodName(); 

这避免了新的例外。

 private static final String TAG = new RuntimeException().getStackTrace()[0].getClassName();