【问题标题】:How can I use lambda expression here?如何在这里使用 lambda 表达式?
【发布时间】:2020-05-30 13:13:44
【问题描述】:

我有我的自定义 GetVolley 类

class GetVolley(private val mContext: Context, private val url: String, private val onVolleySuccess: OnVolleySuccess?, private val mOnVolleyError: OnVolleyError?, private val mOnVolleyEnd: OnVolleyEnd?) {
    private fun getDataVolley() {
        Log.d("GetVolleyUrl", url)
        val request = JsonObjectRequest(Request.Method.GET, url, null, Response.Listener { response: JSONObject ->
            Log.d("GetVolleyResult", response.toString())
            if (response.has("result") && response.getBoolean("result")) {
                onVolleySuccess?.onSuccess(response)
            } else if (response.has("message")) {
                if (mOnVolleyError != null) mOnVolleyError.onError(response.getString("message"))
                else Toast.makeText(mContext, response.getString("message"), Toast.LENGTH_LONG).show()
            }
            mOnVolleyEnd?.onEnd()
        }, Response.ErrorListener { volleyError: VolleyError ->
            Log.d("GetVolleyError", volleyError.message.toString())
            val errorMessage: String = if (volleyError is NetworkError || volleyError is AuthFailureError) {
                "No Internet…"
            } else {
                "Undefinded error"
            }
            if (mOnVolleyError != null) mOnVolleyError.onError(errorMessage)
            else Toast.makeText(mContext, errorMessage, Toast.LENGTH_LONG).show()
            mOnVolleyEnd?.onEnd()
        })
        Volley.newRequestQueue(mContext).add(request)
    }

    init {
        getDataVolley()
    }
}

不同文件中的接口:

interface OnVolleySuccess {
    fun onSuccess(response: JSONObject)
}
______________________________________
interface OnVolleyError {
    fun onError(error: String)
}
______________________________________
interface OnVolleyEnd {
    fun onEnd()
}

当我使用我的自定义 GetVolley 请求时。我的代码如下:

GetVolley(this, url, object : OnVolleySuccess {
    override fun onSuccess(response: JSONObject) {
        parseResponse(response)
    }
}, object : OnVolleyError {
    override fun onError(error: String) {
        showError(error)
    }
}, null)

我希望它看起来像这样:

GetVolley(this, url, response -> {
    parseResponse(response)
}, error -> {
    showError(error)
}, null)

我所有的回调都可以为空,所以我可以将 onVolleySuccess、onVolleyError、onVolleyEnd 设置为空。

【问题讨论】:

    标签: kotlin lambda android-volley


    【解决方案1】:

    你什么叫SAM conversions(单一抽象方法)。它仅适用于 Java 接口,但从 Kotlin 1.4 起将适用于 Kotlin 接口。 (见this article)。现在,如果你想要 lambdas,请使用 lambdas:

    class GetVolley(
        private val mContext: Context, 
        private val url: String, 
        private val onVolleySuccess: ((response: JSONObject) -> Unit)?, 
        private val mOnVolleyError: ((error: String) -> Unit)?, 
        private val mOnVolleyEnd: (() -> Unit)?
    ) {
    

    而不是这样做:

    onVolleySuccess?.onSuccess(response)
    

    你这样做:

    onVolleySuccess?.invoke(response)
    

    【讨论】:

    • 版本 1.4 还没有发布,我可以在生产中使用这个版本吗?或者我应该等它发布?
    • 您可以使用它(请参阅@AnimeshSahu 的回答),但我强烈建议您改用 lambda,它更惯用。 1.4 还不稳定。
    • @ShuhratjonJumaev EAP 尚未准备好投入生产 kotlinlang.org/eap By participating in the EAP, you expressly acknowledge that the EAP version may not be reliable, may not work as intended, and may contain errors.
    • @Nicolas 我使用了您的解决方案。它在没有额外接口的情况下工作,我的代码看起来更好,我喜欢。这并不重要,顺便说一句,我的代码现在看起来像这样:``` GetVolley(this, url, {//it: JSONObject parseResponse(it) }, {//it: JSONObject showError(it) }, null) ``` 可以将“它”替换为“响应”吗?
    • 是的,it 只是默认名称。你可以写{ response ->来命名。
    【解决方案2】:

    注意:如果您愿意,请使用 Nicolas 解决方案,因为如果您不想在 Java 中使用这些类,它会原生使用 lambda

    SAM 转换,即使用 lambda 进行回调转换的接口仅在 Kotlin 1.4 之后可用,它在 EAP(早期访问程序)中。

    如果您有几个月前发布的 Kotlin 1.4-M1,您可以使用 fun 关键字声明您的接口,这将使其可用作 lambda。

    fun interface OnVolleySuccess {
        fun onSuccess(response: JSONObject)
    }
    fun interface OnVolleyError {
        fun onError(error: String)
    }
    fun interface OnVolleyEnd {
        fun onEnd()
    }
    

    现在你可以像这样使用它了:

    GetVolley(this, url, { response ->
        parseResponse(response)
    }, { error ->
        showError(error)
    }, null)
    
    // or simply
    GetVolley(this, url, { parseResponse(it) }, { showError(it) }, null)
    

    如果您在采用 Kotlin 1.4 时遇到困难,请注意以下问题:

    // add/change these in build.gradle:
    plugins {
        id 'org.jetbrains.kotlin.jvm' version '1.4-M1'
        // ...
    }
    
    repositories {
        // ...
        maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
    }
    
    // add these in settings.gradle
    pluginManagement {
        repositories {
            mavenCentral()
            maven { "https://dl.bintray.com/kotlin/kotlin-eap" }
            maven { "https://plugins.gradle.org/m2/" }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-06-15
      • 1970-01-01
      • 2018-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多