英文:
Fatal exception with Kotlin Coroutine without proper error message
问题
我正在学习 Kotlin 协程,并尝试构建一个带有一些 API 请求的简单应用。不幸的是,我遇到了一个错误,这个错误没有提供详细信息,以下是日志中的全部内容:
FATAL EXCEPTION: main
Process: com.tests.myapp, PID: 14743
这是我的简单协程,它只是调用一个 API 端点。我从这个教程中复制了语法。
CoroutineScope(Dispatchers.Main).launch {
API.call().registration();
}
对于 Kotlin 协程,我使用的版本是:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
对于网络库,我使用的是 Retrofit,如下所示:
object API {
private const val BASE_URL = "http://my-test-url-comes-here.com"
private val okHttpClient = OkHttpClient()
.newBuilder()
.addInterceptor(RequestInterceptor)
.build()
private fun getClient(): Retrofit =
Retrofit.Builder()
.client(okHttpClient)
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
fun call(): Endpoints {
return getClient().create(Endpoints::class.java)
}
}
有什么见解吗?
英文:
I'm learning Kotlin Coroutines and I'm trying to build a simple app with some API requests.
Unfortunately I've stumbled upon an error which is not really talkative, this is all I have in the logs:
FATAL EXCEPTION: main
Process: com.tests.myapp, PID: 14743
This is my simple coroutine which would simply call an API endpoint. I've copied the syntax from this tutorial.
CoroutineScope(Dispatchers.Main).launch {
API.call().registration();
}
For Kotlin Coroutines I use this version:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
And for the networking library I have Retrofit like this:
object API {
private const val BASE_URL = "http://my-test-url-comes-here.com"
private val okHttpClient = OkHttpClient()
.newBuilder()
.addInterceptor(RequestInterceptor)
.build()
private fun getClient(): Retrofit =
Retrofit.Builder()
.client(okHttpClient)
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
fun call(): Endpoints {
return getClient().create(Endpoints::class.java)
}
}
Any insights?
答案1
得分: 1
我认为你应该使用 Dispatchers.IO
,因为你在调用一个使用网络的函数。通过传递 Dispatcher.Main
,你正在要求协程作用域使用 UI 线程,这将导致主线程上的网络异常。
所以,你可以这样做:
CoroutineScope(Dispatchers.IO /* 在这里替换为 IO */).launch {
API.call().registration();
}
英文:
I think you should use Dispatchers.IO
because you are calling a functon that uses network. by passing Dispatcher.Main
, you are asking coroutinScope to use UI thread. that gives a Network on Main thread Exception.
so,
CoroutineScope(Dispatchers.IO /* replace Main with IO here */).launch {
API.call().registration();
}
答案2
得分: 0
尝试使用Dispatchers.IO,并建议您仅创建一次您的API服务,就像这样检查您的清单文件 - 您应该向您的应用程序添加Internet权限以进行网络调用。
object API {
private const val BASE_URL = "http://my-test-url-comes-here.com"
private val okHttpClient = OkHttpClient()
.newBuilder()
.addInterceptor(RequestInterceptor)
.build()
private val client by lazy {
Retrofit.Builder()
.client(okHttpClient)
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
val api by lazy {
client.create(Endpoints::class.java)
}
}
注意:我在这里写的lazy初始化程序只是一个示例,您也可以使用非懒惰的初始化程序。
英文:
try to use Dispatchers.IO and also I would suggest you to create your api service only once like this and check you manifest file - you should add internet permission to your app, to make network calls
object API {
private const val BASE_URL = "http://my-test-url-comes-here.com"
private val okHttpClient = OkHttpClient()
.newBuilder()
.addInterceptor(RequestInterceptor)
.build()
private val client by lazy {
Retrofit.Builder()
.client(okHttpClient)
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
val api by lazy {
client.create(Endpoints::class.java)
}
}
NOTE: the lazy initializer I wrote here is just sample you can also you non-lazy initializer
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论