0

I just tried today to develop a new app in Kotlin about grabbing data from any website using Volley. I encounter a problem when creating an StringRequest instance and I don't know how to solve it.

I get this error when creating object Response.Listener<String> and Response.ErrorListener:

The class doesn't have a constructor

The code is below:

class MainActivity : AppCompatActivity() {

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

        Btn.setOnClickListener {
            val queue = Volley.newRequestQueue(this)
            val url = "http://www.google.com"
            val stringRequest = StringRequest(Request.Method.GET, url,
                    object:Response.Listener<String>() {
                        override  fun onResponse(response:String) {
                            // Display the first 500 characters of the response string.
                            textView.setText("Response is: " + response.substring(0, 500))
                        }
                    }, object:Response.ErrorListener() {
                        override fun onErrorResponse(error:VolleyError) {
                            textView.setText("That didn't work!")
                        }
                    })
            queue.add(stringRequest)
        }
    }
}

Thank you in advance.

0

1 Answer 1

3

When you create an object which implements an interface, curly braces () is not needed, since interface does not have a constructor. On the other hand, when you create an object which extends a class, curly braces is needed. For example:

interface MyListener {
    fun success()
}

abstract class MyAbstractClass {
    abstract fun fail()
}

//Create an object which extends MyAbstractClass and implements MyListener
val impl = object: MyAbstractClass(), MyListener {
    override fun success() { TODO() }
    override fun fail() { TODO() }
}

So, you need to remove the curly braces for Response.Listener and Response.ErrorListener:

val stringRequest = StringRequest(Request.Method.GET, url,
        object: Response.Listener<String> {
            override fun onResponse(response:String) {
                // Display the first 500 characters of the response string.
                textView.setText("Response is: " + response.substring(0, 500))
            }
        }, object: Response.ErrorListener {
            override fun onErrorResponse(error:VolleyError) {
                textView.setText("That didn't work!")
            }
        })

Since Response.Listener and Response.ErrorListener is SAM type defined in Java and Kotlin supports SAM conversions, you may simplify the code in this way:

val stringRequest = StringRequest(Request.Method.GET, url,
        Response.Listener<String> {
            response ->
                // Display the first 500 characters of the response string.
                textView.setText("Response is: " + response.substring(0, 500))
        }, Response.ErrorListener {
            error ->
                textView.setText("That didn't work!")
        })

//Or even
val stringRequest = StringRequest(Request.Method.GET, url,
        Response.Listener<String> {
            // Display the first 500 characters of the response string.
            textView.setText("Response is: " + it.substring(0, 500))
        }, Response.ErrorListener {
            textView.setText("That didn't work!")
        })

Notes: SAM conversion is not supported for interfaces defined in Kotlin at this moment.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.