Kotlin协程学习中使用协程相关日志是学习协程的重要手段,例如打印协程名。默认情况下协程相关的日志是关闭的,那如何打开相关日志呢?这里主要分两种,单元测试中的日志以及Android工程中的日志,下面将分别进行讲解。此外,对于使用基础设施(startCoroutine和createCoroutine)创建的协程,使用上述两种方法无法进行日志调试,本文将介绍一种其他的便捷方法打印日志。
1. 单元测试协程debug模式
在单元测试中设置协程debug模式,可以使用Thread.currentThread().name将当前线程和协程打印出来。那如何开启debug模式呢?这需要在configurations中将VM options设置-Dkotlinx.coroutines.debug=on,或者-ea。示意图如下所示。先打开Android Studio中相应单元测试的Configurations。点击图1的Edit Configuration,进入图2.
图 1
然后在图2中将VM options设置为-Dkotlinx.coroutines.debug=on,或者-ea。如图2.
图 2
以下是测试代码。
class ExampleUnitTest {
@Test
fun logTest() {
name()
}
fun name() = runBlocking {
async {
log("1")
}
async {
log("2")
}
}
fun log(msg: String) = println("[${Thread.currentThread().name}] $msg")\
}
当debug模式关闭时,打印日志为:
[main] 1
[main] 2
debug模式开启时,日志为:
[main @coroutine#2] 1
[main @coroutine#2] 2
2. Android工程协程debug模式
Android工程中打开协程debug模式,无法直接在工程中进行设置,而是需要在Android代码中设置相应属性。设置代码如下:
System.setProperty("kotlinx.coroutines.debug", "on" )
一种常用的方式是在Application初始化的时候进行设置。代码如下:
public class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
System.setProperty("kotlinx.coroutines.debug", "on" )
}
}
3.基础协程日志
对于使用createCoroutine和startCoroutine函数创建的协程,本文统一称为基础协程。对于这种类型的协程,即使打开了协程的debug模式,在Thread.currentThread().name中也不会打印协程名,因此不方便进行调试。此处可以使用另一种方式打印协程名。
我们知道我们可以通过CoroutineContext设置协程名,并且在协程中,通过coroutineContext[CoroutineName]可以打印协程的名字。既然如此,对于每个要调试的协程,我们可以先设置其名字,然后在日志打印处将其名字打印出来,就可以达到增加协程调试日志的效果了。
测试代码如下所示。
class LogTest {
@Test
fun logTest() {
suspend {
println ("Thread name: ${Thread.currentThread().name}; Coroutine Name: ${coroutineContext[CoroutineName]}")
}.startCoroutine(object : Continuation<Unit> {
override val context = EmptyCoroutineContext + CoroutineName("CustomCoroutine")
override fun resumeWith(result: Result<Unit>) {
result.getOrThrow()
}
})
}
}
以上代码打印结果如下:
Thread name: Test worker; Coroutine Name: CoroutineName(CustomCoroutine)
可见即使开启了协程debug模式,Thread.currentThread().name还是未打印协程名。但是我们可以通过coroutineContext[CoroutineName]将协程名手动打印出来。