我正在尝试在应用程序中创建日志系统。我正在考虑收集日志并将其保存在一个文件中。我的想法是使用Kotlin协程来做这件事。所以我做了这个:
object LoggingModule {
private val sdfTime = SimpleDateFormat("HH:mm:ss.SSS", Locale.US)
fun saveLog(tag: String, event: String, t: Throwable?) {
if (t == null) {
Log.v(tag, event)
} else {
Log.e(tag, event, t)
}
val fileName = tag + ".txt"
writeLogToFile(fileName, Date(System.currentTimeMillis()), event, t)
}
private fun writeLogToFile(fileName: String, time: Date, note: String, throwable: Throwable?) {
val directory = File(Environment.getExternalStorageDirectory(), "APP_NAME")
if (createDirIfNotExist(directory)) {
val fileLogsDirectory = File(directory, fileName)
val logToSave = sdfTime.format(time) + " " + note
CoroutineScope(Dispatchers.IO).launch {
saveLogInFile(logToSave, directory, throwable)
}
}
}
private suspend fun saveLogInFile(logToSave: String, directory: File, throwable: Throwable?) {
withContext(Dispatchers.IO) {
try {
val pw = PrintWriter(FileWriter(directory, true))
pw.println(logToSave)
throwable?.printStackTrace(pw)
pw.close()
} catch (e: IOException) {
Log.e("LogSystem", "Error writing to the log file", e)
}
}
}
}
我想请你帮助我理解我做错了什么。我以为当我使用暂停方法时,它会被阻止,然后会以正确的顺序执行。当我需要同步顺序时,使用协程保存到文件是个好主意吗?
使用示例:
LoggingModule.saveLog("ACCOUNT", "user logged successful")
1条答案
按热度按时间83qze16e1#
Suspend函数调用在同一个协程中按顺序执行,
writeLogToFile
函数每次被调用都会创建一个新的协程,因此saveLogInFile
调用之间没有协调。这可以通过一个参与者协程通道来实现,它允许你发送消息给它,让它以有序的方式处理。参与者计划在未来被弃用或删除,所以会有一个编译器警告使用“过时的API”。然而,参与者的替代品不会很快到来。
首先为要发布的数据创建一个 Package 器类:
此外,创建一个CoroutineScope供整个对象使用,而不是重复创建新的对象。
然后创建一个Actor,它将一次处理一条消息,在调用suspend函数
saveLogInFile
或等待另一条消息时挂起。然后修改
writeLogToFile
函数,将消息发送给参与者,而不是直接调用saveLogInFile
。下面是我认为不使用
actor()
也能做到的方法:然后发送到这个频道而不是演员。