有几点需要澄清,这不是重复的问题,正如有人建议的那样:

  • 这是由较长的日志标记名称引起的“运行时崩溃”。即okhttp3.mockwebserver.MockWebServer,这是,而不是IDE棉绒错误
  • 此崩溃是由第三方依赖项(即MockWebServer)引起的。感谢Yuri Schimke提出的错误
    Fix android logging with MockWebServer
  • 我已在答案https://stackoverflow.com/a/63388805/8034839中提供了修复程序。

  • 原始问题:
    我正在使用ExpressoMockWebServer进行Android Web服务测试,但是遇到以下异常,该异常告诉我日志标签问题:

    详细的堆栈跟踪如下:
    2020-08-13 11:31:13.277 16901-17085/com.xxx.app I/okhttp.OkHttpClient: <-- HTTP FAILED: java.net.SocketTimeoutException: timeout
    2020-08-13 11:31:13.280 16901-17346/com.xxx.app E/AndroidRuntime: FATAL EXCEPTION: MockWebServer TaskRunner
        Process: com.xxx.app, PID: 16901
        java.lang.IllegalArgumentException: Log tag "okhttp3.mockwebserver.MockWebServer" exceeds limit of 23 characters
    
            at android.util.Log.isLoggable(Native Method)
            at okhttp3.internal.platform.android.AndroidLog.androidLog$okhttp(AndroidLog.kt:66)
            at okhttp3.internal.platform.android.AndroidLogHandler.publish(AndroidLog.kt:39)
            at java.util.logging.Logger.log(Logger.java:615)
            at java.util.logging.Logger.doLog(Logger.java:636)
            at java.util.logging.Logger.log(Logger.java:725)
            at okhttp3.mockwebserver.MockWebServer$serveConnection$$inlined$execute$1.runOnce(TaskQueue.kt:224)
            at okhttp3.internal.concurrent.TaskRunner.runTask(TaskRunner.kt:116)
            at okhttp3.internal.concurrent.TaskRunner.access$runTask(TaskRunner.kt:42)
            at okhttp3.internal.concurrent.TaskRunner$runnable$1.run(TaskRunner.kt:65)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
            at java.lang.Thread.run(Thread.java:762)
    2020-08-13 11:31:13.293 16901-17346/com.xxx.app I/Process: Sending signal. PID: 16901 SIG: 9
    

    最佳答案

    在研究MockWebServer.kt的源代码之后,我已经找到了解决此问题的方法。在此文件中,有一个类似下面的属性:

    private val logger = Logger.getLogger(MockWebServer::class.java.name)
    
    MockWebServer::class.java.name将返回完整的类名okhttp3.mockwebserver.MockWebServer,显然,此名称作为Android日志标签已超过23个字符。该修复程序使用Kotlin反射来替换logger属性。反射代码如下:
    fun <T : Any> T.setPrivateProperty(variableName: String, data: Any): Any? {
        return javaClass.getDeclaredField(variableName).let { field ->
            field.isAccessible = true
            field.set(this, data)
            return@let field.get(this)
        }
    }
    
    
    @before方法内,使用simpleName设置logger标记
    val mockWebServer = MockWebServer() // this is declared inside test class.
    
    @Before
    fun setup() {
    
        mockWebServer.setAndReturnPrivateProperty("logger",
            Logger.getLogger(MockWebServer::class.java.simpleName))
    
        mockWebServer.start(8080)
    }
    
    MockWebServer::class.java.simpleName将返回较短的类名并解决该问题。

    07-24 09:15