Android Studio converting Java to Kotlin error Can

2019-04-25 11:21发布

问题:

I'm new to Android development (started 6 months ago) and would like to move from Java to Kotlin. I've converted my project to Kotlin and fixed all issues but one and I can't figure out how to fix it.

I'm attempting to retrieve a JSONArray (as seen in class JsonManager) and use the retrieved data in a second class called DataDisplayPage via a method call.

I am getting the following console errors, which occur at this line of the second class: jManager.fetch_data{ theJsonArray ->.

Cannot infer a type for this parameter. Please specify it explicitly.

Type mismatch: inferred type is (???) -> Unit but OnTaskCompleted was expected

First class JsonManager

interface OnTaskCompleted {
    fun onTaskCompleted(theJsonArray: JSONArray)
}

class JsonManager {
    var listener: OnTaskCompleted? = null

    init {
        Log.d("JsonManager", "Instance created")
    }

    fun fetch_data(callback : OnTaskCompleted) {
        listener = callback
         val url ="https://someURL"

        AndroidNetworking.get(url)
            .build()
            .getAsJSONArray(object : JSONArrayRequestListener {
                override fun onResponse(response: JSONArray) {
                    listener?.onTaskCompleted(response)
                }

                override fun onError(anError: ANError) {
                    Log.d("error", anError.toString())
                }
            })

}

Second class DataDisplayPage

class DataDisplayPage : AppCompatActivity()

    fun onStartUp() {

        val jManager = JsonManager()

        jManager.fetch_data{ theJsonArray  ->
            val newData = DepData()
            newData.setCellData(theJsonArray as JSONArray)
        }
    }
}

回答1:

As of now, you can't use SAM conversion for interfaces defined in Kotlin. There are a couple things you can do to solve your problem though.

  1. If you define your interface in Java, SAM conversion will start working, and your current code will work without any other changes.

  2. If you want to use an interface as the parameter of the fetch_data method, and you want it to be written in Kotlin, you'll have to pass in an object that implements it, which is a slightly verbose, Java-like solution:

    jmManager.fetch_data(object: OnTaskCompleted {
        override fun onTaskCompleted(theJsonArray: JSONArray) {
            // ...
        }
    })
    
  3. If you want a nice pure Kotlin solution, just get rid of the interface, and have the fetch_data function take a function as its parameter instead of the interface (again, your current code in DataDisplayPage will work with this):

    fun fetch_data(callback: (JSONArray) -> Unit) { 
        // ...
        listener?.onTaskCompleted(response)
        callback(response)
        // ...
    }