5

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.

Vasily Kabunov
  • 6,511
  • 13
  • 49
  • 53

2 Answers2

5

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

miensol
  • 39,733
  • 7
  • 116
  • 112
  • Actually, i've been able to update textView1 from uiThread and from the asynchronous thread, so that's not actually the problem, although the way you put it is the proper way to use it. – Gonzalo Merino May 17 '16 at 08:23
0

The problem turned out to be a lot more basic than what I was thinking. It was a problem of compatibility apparently from having an older version of Android Studio running with the new version 1.0.2 of the Kotlin plugin and, again, apparently the function readText was not working properly and therefore I wasn't getting anything from it.

Anyway, I updated Android Studio, with the latest version of Kotlin and it started working fine, although I'm going to see if I can find out what it was that was causing the problem inside readText.