简体   繁体   English

Kotlin OkHTTP android.os.NetworkOnMainThreadException

[英]Kotlin OkHTTP android.os.NetworkOnMainThreadException

I am sending http request with kotlin and getting this error我正在使用 kotlin 发送 http 请求并收到此错误

Error: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxx/xxx.android.ui.xxx}: android.os.NetworkOnMainThreadException错误: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xxx/xxx.android.ui.xxx}: android.os.NetworkOnMainThreadException

Additional info: GET request needs to work first.附加信息: GET 请求需要首先工作。 Because the process proceeds according to the response from the URL.因为该过程根据 URL 的响应进行。

My Code:我的代码:

override fun onCreate(savedInstanceState: Bundle?) {

    setTheme(R.style.AppTheme_MainActivity)
    super.onCreate(savedInstanceState)

    val request = Request.Builder()
        .url("https://publicobject.com/helloworld.txt")
        .build()

    client.newCall(request).execute().use { response ->
        if (!response.isSuccessful) throw IOException("Unexpected code $response")

    
    }

  
}

Android main components, like Activities , BroadcastReceiver etc, are running in the Main Thread . Android 主要组件,如ActivitiesBroadcastReceiver等,都在主线程中运行。 You can't make a network request (or another potentially long running operation) in the Main Thread .您不能在Main Thread中发出网络请求(或其他可能长时间运行的操作)。 You need to schedule it in the background(worker) thread.您需要在后台(工作者)线程中安排它。 By using Call.execute() method you synchronously send the request.通过使用Call.execute()方法,您可以同步发送请求。 ie in the Main Thread.即在主线程中。 You can use method Call.enqueue() to asynchronously send the request:您可以使用方法Call.enqueue()异步发送请求:

client.newCall(request).enqueue(object : Callback<Response> {
    override fun onResponse(call: Call<Response>, response: Response<Response>
    ) {
        // handle response
    }

    override fun onFailure(call: Call<ApiResponse>, t: Throwable) {
       // handle error
    }

})

There is also another approach of making and handling the request, using Kotlin Coroutines :还有另一种发出和处理请求的方法,使用Kotlin Coroutines

// suspendCoroutine - suspends a coroutine until request is executed
suspend fun makeRequest(): String = suspendCoroutine { continuation ->
    client.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) {
            continuation.resumeWithException(e) // resume calling coroutine
            e.printStackTrace()
        }

        override fun onResponse(call: Call, response: Response) {
            response.use {
                continuation.resume(response.body!!.string()) // resume calling coroutine
            }
        }
    })
}

override fun onCreate(savedInstanceState: Bundle?) {

    // ...
    
    lifecycle.coroutineScope.launch { // launching a coroutine
        val result = makeRequest()
        // do something with result
        // save to Preferences
        getPreferences(MODE_PRIVATE).edit().putString("val001", result).apply(); //save prefences
        println("Request complete")
    }
  
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM