在Kotlin中定义log TAG常量的最佳方法是什么?

Mar*_*lev 56 java android constants kotlin

我正在Android应用程序中创建我的第一个Kotlin类.通常为了记录目的,我有一个名字常量TAG.我在Java中会做的是:

private static final String TAG = MyClass.class.getSimpleName();
Run Code Online (Sandbox Code Playgroud)

我知道在Kotlin课程中我可以TAG用这种方式创建:

private val TAG = MyClass::class.java.simpleName
Run Code Online (Sandbox Code Playgroud)

对于使用Java和Kotlin的项目来说这是可以的,但是如果我开始一个仅在Kotlin中的新项目呢?我如何定义那里TAG不变?还有更多的Kotlin方式我没有这种奇怪的结构class.java.simpleName吗?

Gab*_*tti 35

通常,常量都是大写字母(例如FOO)并位于伴随对象中:

class MyClass {
    companion object {
        public const val FOO = 1

    }
}
Run Code Online (Sandbox Code Playgroud)

并定义您可以使用的TAG字段:

private val TAG = MyClass::class.qualifiedName
Run Code Online (Sandbox Code Playgroud)

  • 嗯,根据Android Studio的警告,`MyClass :: class.qualifiedName`需要反射,这极大地增加了应用程序的复杂性,需要额外的jar文件.有没有更简单的方法来完成这个哦 - 如此常见的任务? (22认同)
  • @ScottBiggs如何使用MyClass :: class.java.simpleName`? (5认同)
  • @EnamulHaque `const` 值必须是编译时常量。由于 Kotlin 没有像 `nameof` 这样的东西,它不能保证该语句始终具有相同的值。此外,正如 Gabriele Mariotti 所说,答案中没有使用 `const`。 (2认同)

Fre*_*ros 34

此扩展允许我们在任何类中使用TAG

val Any.TAG: String
    get() {
        val tag = javaClass.simpleName
        return if (tag.length <= 23) tag else tag.substring(0, 23)
    }

//usage
Log.e(TAG,"some value")
Run Code Online (Sandbox Code Playgroud)

它还被验证为作为Android有效的日志标记.

  • 刚刚找到匿名解决方案/sf/answers/3914108201/ (3认同)
  • 这要去哪里?什么是扩展? (3认同)
  • 我是 kotlin 的新手,所以一个诚实的问题:这有什么缺点吗(除了匿名内部类)?这似乎是最好的答案,因为我认为这就是 kotlin 扩展的用途。 (2认同)

Rah*_*ari 14

我喜欢TAG成为Fredy Mederos 建议的扩展功能。

扩展他的答案以支持匿名类:

 /**
 * extension function to provide TAG value
 */
val Any.TAG: String
    get() {
        return if (!javaClass.isAnonymousClass) {
            val name = javaClass.simpleName
            if (name.length <= 23) name else name.substring(0, 23)// first 23 chars
        } else {
            val name = javaClass.name
            if (name.length <= 23) name else name.substring(name.length - 23, name.length)// last 23 chars
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案,但从 API 24 开始,没有长度限制,因此如果您的应用程序的最小 SDK 为 24+,您可以取消长度检查。 (2认同)

use*_*708 11

在Kotlin中,您可以创建一个扩展,并将标记作为方法调用.这意味着你永远不必在每个类中定义它,我们可以在每次调用方法时动态构造它:

inline fun <reified T> T.TAG(): String = T::class.java.simpleName
Run Code Online (Sandbox Code Playgroud)


Yar*_*lyk 10

通常建议的使用companion objectgenerate的方法会生成static final伴随类的额外实例,因此性能和内存都很差。

最好的方法(恕我直言)

将日志标记定义为顶级常量,因此仅生成额外的类(MyClassKt),但companion object与之相比,将没有该类的static final实例(也没有任何实例):

private const val TAG = "MyLogTag"

class MyClass {

    fun logMe() {
        Log.w(TAG, "Message")
    }
}
Run Code Online (Sandbox Code Playgroud)

另外一个选项

使用正常val。尽管看到日志标记不是全大写的常量看起来很不寻常,但这不会生成任何类并且开销最少。

class MyClass {

    private val tag = "myLogTag"

    fun logMe() {
        Log.w(tag, "Message")
    }
}
Run Code Online (Sandbox Code Playgroud)


nic*_*zjr 9

简单地做以下工作对我有用.

private val TAG = this::class.java.simpleName
Run Code Online (Sandbox Code Playgroud)


Pav*_*kov 9

最好的登录方式(恕我直言)是使用 Timber:https : //github.com/JakeWharton/timber

但是如果你不想使用图书馆,那么

TAG 可以定义为内联扩展属性(例如 in Extensions.kt):

inline val <reified T> T.TAG: String
    get() = T::class.java.simpleName
Run Code Online (Sandbox Code Playgroud)

一些更多的扩展,不要一直写 TAG Log.d(TAG, "")

inline fun <reified T> T.logv(message: String) = Log.v(TAG, message)
inline fun <reified T> T.logi(message: String) = Log.i(TAG, message)
inline fun <reified T> T.logw(message: String) = Log.w(TAG, message)
inline fun <reified T> T.logd(message: String) = Log.d(TAG, message)
inline fun <reified T> T.loge(message: String) = Log.e(TAG, message)
Run Code Online (Sandbox Code Playgroud)

然后你可以在任何类中使用它们:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    logd("Activity created")
}
Run Code Online (Sandbox Code Playgroud)


And*_*ang 5

您可以TAG通过@JvmField以下方式定义您的:

companion object {
    @JvmField val TAG: String = MyClass::class.java.simpleName
}
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,您可以阅读本文:Kotlin的隐藏成本

  • 您的消息来源说:“实际上,此注释仅是出于Java兼容性的原因而创建的,我绝对不建议您使用晦涩的互操作注释将您美丽的Kotlin代码弄乱”。那么为什么建议您使用@JvmField? (3认同)