E/AndroidRuntime:致命异常:main 和 Coroutine,Retrofit2
E/AndroidRuntime: FATAL EXCEPTION: main and Coroutine, Retrofit2
我刚开始学习kotlin,我的第一个应用使用了Retrofit2和Coroutine,但是有问题。我有一些错误,但是协程的堆栈跟踪信息非常少。也许有人会发现错误或知道热点以使堆栈跟踪提供更多信息。
API服务:
const val API_KEY = "Bcae2032bb596c73b10bdab625c037da"
interface CurrencyApi {
//https://api.currencystack.io/currency?base=USD&target=EUR&apikey=Bcae2032bb596c73b10bdab625c037da
@GET("currency")
fun getCurrentCurrency(
@Query("base") base: String,
@Query("target") target: String
): Deferred<Currency>
companion object {
operator fun invoke(): CurrencyApi {
val requestInterceptor = Interceptor { chain ->
val url = chain.request()
.url()
.newBuilder()
.addQueryParameter("key", API_KEY)
.build()
val request = chain.request()
.newBuilder()
.url(url)
.build()
return@Interceptor chain.proceed(request)
}
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(requestInterceptor)
.build()
return Retrofit.Builder()
.client(okHttpClient)
.baseUrl("https://api.currencystack.io/")
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(CurrencyApi::class.java)
}
}
Activity:
class MainActivity : AppCompatActivity(), AdapterView.OnItemSelectedListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
val model = ViewModelProviders.of(this).get(MainViewModel::class.java)
val apiService = CurrencyApi()
GlobalScope.launch(Dispatchers.Main) {
val currency = apiService.getCurrentCurrency("PLN", "EUR").await()
return@launch try {
text_view_test.text = currency.toString()
} catch (e: Exception) {
}
}
Logcat:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.daniellachacz.currencyconverter, PID: 10924
retrofit2.HttpException: HTTP 400
at com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory$BodyCallAdapter$adapt.onResponse(CoroutineCallAdapterFactory.kt:104)
at retrofit2.OkHttpCall.onResponse(OkHttpCall.java:123)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
您收到服务器错误 400 Bad Request
响应。此状态代码表示由于语法无效,服务器无法理解请求。尝试调试或放置一些日志,看看您真正发送到服务器的内容。我认为调试的好地方是 Interceptor
接口的实现。
如@Sergey 所说,这是服务器错误。
在我的例子中,它无法被 API 捕获,服务器写道:An internal server error occurred.
(代码 500)而不是 JSON。
将@GET(currency)
替换为@GET(currency.json)
我刚开始学习kotlin,我的第一个应用使用了Retrofit2和Coroutine,但是有问题。我有一些错误,但是协程的堆栈跟踪信息非常少。也许有人会发现错误或知道热点以使堆栈跟踪提供更多信息。
API服务:
const val API_KEY = "Bcae2032bb596c73b10bdab625c037da"
interface CurrencyApi {
//https://api.currencystack.io/currency?base=USD&target=EUR&apikey=Bcae2032bb596c73b10bdab625c037da
@GET("currency")
fun getCurrentCurrency(
@Query("base") base: String,
@Query("target") target: String
): Deferred<Currency>
companion object {
operator fun invoke(): CurrencyApi {
val requestInterceptor = Interceptor { chain ->
val url = chain.request()
.url()
.newBuilder()
.addQueryParameter("key", API_KEY)
.build()
val request = chain.request()
.newBuilder()
.url(url)
.build()
return@Interceptor chain.proceed(request)
}
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(requestInterceptor)
.build()
return Retrofit.Builder()
.client(okHttpClient)
.baseUrl("https://api.currencystack.io/")
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(CurrencyApi::class.java)
}
}
Activity:
class MainActivity : AppCompatActivity(), AdapterView.OnItemSelectedListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
val model = ViewModelProviders.of(this).get(MainViewModel::class.java)
val apiService = CurrencyApi()
GlobalScope.launch(Dispatchers.Main) {
val currency = apiService.getCurrentCurrency("PLN", "EUR").await()
return@launch try {
text_view_test.text = currency.toString()
} catch (e: Exception) {
}
}
Logcat:
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.daniellachacz.currencyconverter, PID: 10924 retrofit2.HttpException: HTTP 400 at com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory$BodyCallAdapter$adapt.onResponse(CoroutineCallAdapterFactory.kt:104) at retrofit2.OkHttpCall.onResponse(OkHttpCall.java:123) at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153) at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818)
您收到服务器错误 400 Bad Request
响应。此状态代码表示由于语法无效,服务器无法理解请求。尝试调试或放置一些日志,看看您真正发送到服务器的内容。我认为调试的好地方是 Interceptor
接口的实现。
如@Sergey 所说,这是服务器错误。
在我的例子中,它无法被 API 捕获,服务器写道:An internal server error occurred.
(代码 500)而不是 JSON。
将@GET(currency)
替换为@GET(currency.json)