“Fatal exception with Kotlin Coroutine without proper error message”

huangapple go评论73阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年2月14日 02:27:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75439876.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定