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.

BakaWaii
  • 6,732
  • 4
  • 29
  • 41
Ali Barani
  • 238
  • 2
  • 7
  • 17

1 Answers1

2

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.

BakaWaii
  • 6,732
  • 4
  • 29
  • 41