okhttp 中的非 https 请求出现 NetworkOnMainThreadError

问题描述 投票:0回答:1

我正在开发使用我的 API 的 Android 应用程序。我想在应用程序中以测试模式使用 API,但是当我尝试调用不使用 https 的请求 API 时,会发生 NetworkOnMainThreadError

我使用 OkHTTP

请求示例:

val baseURL = "http://192.168.1.100:5555/api"
val authToken = "TOKEN"
val client = OkHttpClient.Builder().cache(
        Cache(context.cacheDir, 20 * 1024 * 1024)
    ).build()

CoroutineScope(Dispatchers.Main).launch {
    val urlBuilder = baseURL.toHttpUrl()
            .newBuilder()
            .addPathSegments("compositions/search")
    response = withContext(Dispatchers.IO) {
        client.newCall(
            Request.Builder()
                .get()
                .url(urlBuilder.build())
                .addHeader("Authorization", "bearer $authToken")
                .build()
        ).execute()
    }
    val body = response.body!!.string()
}

错误示例:

android.os.NetworkOnMainThreadException
 at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1605)
 at java.net.SocketInputStream.read(SocketInputStream.java:175)
 at java.net.SocketInputStream.read(SocketInputStream.java:144)
 at okio.InputStreamSource.read(JvmOkio.kt:94)
 at okio.AsyncTimeout$source$1.read(AsyncTimeout.kt:125)
 at okio.RealBufferedSource.read(RealBufferedSource.kt:189)
 at okhttp3.internal.http1.Http1ExchangeCodec$AbstractSource.read(Http1ExchangeCodec.kt:331)
 at okhttp3.internal.http1.Http1ExchangeCodec$FixedLengthSource.read(Http1ExchangeCodec.kt:368)
 at okhttp3.internal.connection.Exchange$ResponseBodySource.read(Exchange.kt:276)
 at okio.RealBufferedSource.select(RealBufferedSource.kt:229)
 at okhttp3.internal.Util.readBomAsCharset(Util.kt:265)
 at okhttp3.ResponseBody.string(ResponseBody.kt:187)
 at com.vhu.mitsu.api.MitsuAPI.getError(MitsuAPI.kt:145)
 at com.vhu.mitsu.api.MitsuAPI.prolongAuth(MitsuAPI.kt:598)
 at com.vhu.mitsu.api.MitsuAPI$prolongAuth$1.invokeSuspend(Unknown Source:14)
 at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
 at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
 at android.os.Handler.handleCallback(Handler.java:938)
 at android.os.Handler.dispatchMessage(Handler.java:99)
 at android.os.Looper.loop(Looper.java:236)
 at android.app.ActivityThread.main(ActivityThread.java:8057)
 at java.lang.reflect.Method.invoke(Native Method)
 at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:620)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1011)
 Suppressed: android.os.NetworkOnMainThreadException
  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1605)
  at java.net.SocketInputStream.read(SocketInputStream.java:175)
  at java.net.SocketInputStream.read(SocketInputStream.java:144)
  at okio.InputStreamSource.read(JvmOkio.kt:94)
  at okio.AsyncTimeout$source$1.read(AsyncTimeout.kt:125)
  at okio.RealBufferedSource.read(RealBufferedSource.kt:189)
  at okhttp3.internal.http1.Http1ExchangeCodec$AbstractSource.read(Http1ExchangeCodec.kt:331)
  at okhttp3.internal.http1.Http1ExchangeCodec$FixedLengthSource.read(Http1ExchangeCodec.kt:368)
  at okhttp3.internal.Util.skipAll(Util.kt:344)
  at okhttp3.internal.Util.discard(Util.kt:365)
  at okhttp3.internal.http1.Http1ExchangeCodec$FixedLengthSource.close(Http1ExchangeCodec.kt:387)
  at okio.ForwardingSource.close(ForwardingSource.kt:34)
  at okhttp3.internal.connection.Exchange$ResponseBodySource.close(Exchange.kt:309)
  at okio.RealBufferedSource.close(RealBufferedSource.kt:477)
  at kotlin.io.CloseableKt.closeFinally(Closeable.kt:59)
  at okhttp3.ResponseBody.string(ResponseBody.kt:186)
  ... 12 more
 Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@ecd807f, Dispatchers.Main]

我尝试将所有使用服务器响应的代码包装在 withContext(Dispatchers.IO) 中。但它也会引发同样的错误

android kotlin okhttp
1个回答
0
投票

移动:

val body = response.body!!.string()

位于

IO
协程内部:

    response = withContext(Dispatchers.IO) {
        client.newCall(
            Request.Builder()
                .get()
                .url(urlBuilder.build())
                .addHeader("Authorization", "bearer $authToken")
                .build()
        ).execute()

        val body = response.body!!.string()
    }
© www.soinside.com 2019 - 2024. All rights reserved.