如何限制 Logcat 中的相同消息?

How to throttle the same messages in the Logcat?

我需要使用 Log class 记录 Android 应用程序的重要内容。我主要使用调试、信息和错误类型。我的问题是有些日志经常打印到 Logcat 例如GPS 状态,phone 等的免费 space 收听。对于应用程序来说,某些更新之间的差距是至关重要的,无法更改,但我不需要 Logcat 中的那么多重复行.

我的目标是:

我创建了 LogData class:

data class LogData(
    val message: String,
    val type: LogType
)

其中类型是:

enum class LogType {
    DEBUG,
    INFO,
    ERR
}

我想知道是否可以为此使用 RxJava 和一些油门运算符,但我不知道如何准确地考虑相同的消息并忽略它:

        log.throttleFirst(GAP_IN_MS, TimeUnit.MILLISECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe { (message, type) ->
                when(type) {
                    LogType.DEBUG -> debugMessage(message)
                    LogType.INFO -> infoMessage(message)
                    LogType.ERR -> errorMessage(message)
                }
            }

其中 private val log = BehaviorSubject.create<LogData>()

我认为这里不需要 RX,只是对日志的包装。

class MyLogger {

  private val messagesSent = mutableMapOf<LogData, Long>()
  private val timeOut = 1000;  //number of ms that must pass before logging the same object again
  
  fun log(message: LogData) {
    if((messagesSent?.get(message) ?: 0) < System.getCurrentTimeMillis - timeOut) {
      Log.d(message.message)
      messagesSent.put(message, System.getCurrentTimeMillis())
    }
  }
}

然后使用它代替 android 记录器。如果您想要比节流超时更复杂的东西,只需将逻辑放在这里即可。

现在这将随着时间的推移慢慢增加 messagesSent 映射的大小。如果这成为内存问题,您可以创建一个线程或协程,它经常遍历地图并在 timeOut 秒前从地图中驱逐任何东西。

现在您将遇到线程问题。避免它的最简单方法是使用同步映射 class。如果你不想这样做,你可以使用 rx 并让记录器 class 有一个可观察的,让日志将值发布到那个可观察的,并有一个订阅者到那个在我的日志函数中执行逻辑的可观察的现在。这肯定会起作用,尽管我只是使用同步映射 class 来更容易理解代码,除非你有太多的日志语句以至于锁定时间成为一个问题。