1

I am new to kotlin programming and getting one initialization error while trying to close BufferedReader instance. Here is the kotlin class:

package first.kot.kotprac

import android.os.AsyncTask
import android.util.Log
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
import java.net.ResponseCache
import java.net.URL
import javax.net.ssl.HttpsURLConnection

class MyAsyncTask : AsyncTask<Void, Void, Void>() {

    private val TAG = "MyAsyncTask"
    private var responseData = ""

    override fun doInBackground(vararg params: Void?): Void? {

        val reader : BufferedReader

        try{

            val url= URL("vvv")

            val conn = url.openConnection() as HttpsURLConnection

            val responseCode = conn.responseCode

            Log.e(TAG,"Response code: "+responseCode);

            if(responseCode == HttpsURLConnection.HTTP_OK){
                reader = BufferedReader(InputStreamReader(conn.inputStream))

                var sb = StringBuilder()

                reader.lineSequence().forEach {
                    sb.append(it+"\n")
                }

            responseData = sb.toString()

            }


        }catch (e: Exception){
            e.printStackTrace()
        }
        finally {
            if(reader!=null)
            reader.close()       // Error line
        }

        return null
    }
}

I have gone through the following thread:

https://stackoverflow.com/questions/41537638/assignment-not-allowed-in-while-expression

but I am not getting how the second way in the ticked answer will make sure that buffer is closed and my main concern is to solve the current issue too. Please help me to solve this problem.

sak
  • 1,230
  • 18
  • 37

2 Answers2

1

val variables can only be assigned once, and BufferedReader type can never be null.

You would need to replace it with var reader : BufferedReader? = null which is a nullable type initialized to null.

Pawel
  • 15,548
  • 3
  • 36
  • 36
1

You should be using use. From the doc

Executes the given block function on this resource and then closes it down correctly whether an exception is thrown or not.

this way you can avoid the finally block. Read more here

An extensions that read the InputStream in a string:

fun InputStream.readTextAndClose(charset: Charset = Charsets.UTF_8): String {
    return this.bufferedReader(charset).use { it.readText() }
}

and in your case you could replace your code with

responseData = conn.inputStream.readTextAndClose()
Blackbelt
  • 156,034
  • 29
  • 297
  • 305
  • Can you apply the "use" block in my code? I am not getting what is R? – sak Jul 19 '18 at 09:46
  • Got it already, R means Source. It is a more informative answer. Thanks! – sak Jul 19 '18 at 09:55
  • But will you please answer one more thing, What is the use of finally block in kotlin then? – sak Jul 19 '18 at 10:00
  • the same as java. `use` works here because `InputStream` is a `closable` – Blackbelt Jul 19 '18 at 10:01
  • What is not closable then? Is there any list in kotlin which can tell the streams which can't be closed with "USE" block? How do we know? – sak Jul 19 '18 at 10:02
  • 1
    of course. It is [here](https://docs.oracle.com/javase/8/docs/api/java/io/Closeable.html) – Blackbelt Jul 19 '18 at 10:04