Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

API call not working inside Anko Async

I'm trying to make an http request in Android, using Kotlin, and I've come across two ways of doing so.

One is the traditional way, using AsyncTask (not really pretty) which I got to work with the following code (just the doInBackground, as the rest of the class seemed unnecessary):

override fun doInBackground(vararg params: Void?): String? {
    val url = URL("myUrl")
    val httpClient = url.openConnection() as HttpURLConnection
    if(httpClient.getResponseCode() == HttpURLConnection.HTTP_OK){
        try {
            val stream = BufferedInputStream(httpClient.getInputStream())
            val data: String = readStream(inputStream = stream)
            return data;
        } catch (e : Exception) {
            e.printStackTrace()
        } finally {
            httpClient.disconnect()
        }
    }else{
        println("ERROR ${httpClient.getResponseCode()}")
    }
    return null
}

Now, I've come across a library called Anko, which many here know, and I tried to use its DSL for asynchronous tasks. The thing is, I haven't found a lot of info here about Anko for asynchronous tasks, so I thought I would open a new topic to see if someone could walk me through what I'm doing wrong, or what they think I should do to make it work.

The code I wanted to use is the following:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    async() {
        val result = URL("myUrl").readText()
        textView1.setText(result)
    }
}

I tried to keep it as slim as possible so to minimize any potential mistakes, but I must be doing something wrong here because the code inside the async block is not doing anything, yet the app is not crashing and I'm not getting any exceptions. I've tried debugging it using Intellij IDEA, but after the first line inside the async block it stops the debugging while saying "The application is running". My best guess is that it got hung up somewhere in that first line due to the failed connection, but I don't know.

I've also tried to use the regular URL("myUrl").openConnection() inside the async block, but that hasn't worked either.

Anyway, any help would be deeply appreciated.

like image 655
Gonzalo Merino Avatar asked May 15 '16 10:05

Gonzalo Merino


People also ask

How to call an async function from the useeffect hook?

Method 1: Creating async function inside useEffect and calling immediately. In this method, we can create a function inside the first argument of the useEffect hook. For declaring any function as async we need to add the keyword “async” before the declaration of the function.

What is asynchronous communication with an API?

It blocks the flow of the application, thus, the rise in popularity of asynchronous communication. In an asynchronous example, an API calls the bank to ask the same thing, but instead of waiting for the answer it immediately receives a token, like an ID of the question, without waiting for the actual result.

Can we add a “then” statement after the API call?

We can add a “then” statement after the API call so that the code inside our then block gets executed as soon as we get the response from the API. We can add multiple cascading then blocks in the sequence we want to perform the operations.

What is the difference between OpenAPI and asyncapi?

Open API is focused on REST APIs, while AsyncAPI is more about asynchronous APIs in more complex integration scenarios. AsyncAPI creators like to think about their AsyncAPI specification as one of the founding blocks for Event Driven Architecture (EDA), for which OpenAPI was not enough.


1 Answers

The problem textView1 contents not getting updated is caused by calling setText outside of main thread.

The documentation shows a nice example how to properly use async. Take a look at the following adapted version of your code:

async() {
    val result = URL("http://stackoverflow.com/").readText()
    uiThread {
        textView1.text = result
    }
}

PS. While not directly related to the question consider using a nicer http client i.e. Retrofit, OkHttp

like image 131
miensol Avatar answered Sep 22 '22 01:09

miensol