When I'm trying to request an API with khttp
I'm having this issue in an emulator on Android Studio with SDK 28 (Android Pie 9.0)
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.example.corentin.myapplication, PID: 3168
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:354)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.NoSuchFieldException: No field host in class Ljava/net/URL; (declaration of 'java.net.URL' appears in /system/framework/core-oj.jar)
at java.lang.Class.getDeclaredField(Native Method)
at khttp.requests.GenericRequest.toIDN(GenericRequest.kt:193)
at khttp.requests.GenericRequest.makeRoute(GenericRequest.kt:198)
at khttp.requests.GenericRequest.<init>(GenericRequest.kt:128)
at khttp.KHttp.request(KHttp.kt:58)
at khttp.KHttp.get(KHttp.kt:28)
at khttp.KHttp.get$default(KHttp.kt:27)
at com.example.corentin.myapplication.InfoUser.run(InfoUser.kt:29)
at com.example.corentin.myapplication.InfoUser$onCreate$1.invoke(InfoUser.kt:23)
at com.example.corentin.myapplication.InfoUser$onCreate$1.invoke(InfoUser.kt:16)
at com.example.corentin.myapplication.doAsync.doInBackground(InfoUser.kt:11)
at com.example.corentin.myapplication.doAsync.doInBackground(InfoUser.kt:9)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
And this is where the error comes from:
class doAsync(val handler: () -> Unit) : AsyncTask<Void, Void, Void>() {
override fun doInBackground(vararg params: Void?): Void? {
handler()
return null
}
}
class InfoUser : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_info_user)
doAsync {
run("https://api.imgur.com/3/account/xcoco55?client_id=CLIENT ID")
}.execute()
}
fun run(url: String) {
val response = khttp.get(url)
println("Coucou")
if (response.statusCode == 200) {
runOnUiThread {textView.text = response.text}
}
}
}
When I delete the line val response = khttp.get(url)
, or when I launch the application on my mobile phone (Android Oreo 8.1), everything works fine.
Do you think that the error comes from Android 9.0 or from the emulator?
Disclaimer: I was referred to this post via the following request.
This is an issue that is faced when you are targeting Android 9.0 and occurs as @Torben Kohlmeier mentioned because the field is no longer accessible.
You can instead replace your khttp implementation in your modules build.gradle
with the following, which should work as expected.
implementation "io.karn:khttp-android:0.1.0"
The khttp-android
library is a fork of the original khttp library by jkcclemens.
khttp is trying to use reflection to assign a value to the field host
of java.net.URL
.
This is the code: https://github.com/jkcclemens/khttp/blob/94ddc375f77f6b8b4bffd5415f136fe31fc663ae/src/main/kotlin/khttp/requests/GenericRequest.kt#L198
The URL implementation in core-oj.jar obviously does not have that field anymore.
This can only be fixed by changing the khttp code. But it looks like the library is no longer being maintained. The last commit was in September 2017.
I suggest switching to another library like fuel.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With