You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在自定义GetVolley类中使用Lambda表达式简化回调写法?

如何将Volley回调简化为Lambda表达式调用?

你已经封装了GetVolley类来处理Volley的GET请求,现在想把原本需要匿名内部类实现的回调,改成更简洁的Lambda写法对吧?这在Kotlin里完全可以实现,下面分两种方案给你讲解:


方案一:直接替换构造函数参数为函数类型

这种方式不需要修改你现有的三个回调接口,只需要调整GetVolley的构造函数定义,把接口类型换成对应的函数类型,然后在类内部用invoke()来触发回调:

修改后的GetVolley类代码

class GetVolley(
    private val mContext: Context,
    private val url: String,
    private val onVolleySuccess: ((JSONObject) -> Unit)?, // 替换为函数类型
    private val mOnVolleyError: ((String) -> Unit)?,      // 替换为函数类型
    private val mOnVolleyEnd: (() -> Unit)?               // 替换为函数类型
) {
    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?.invoke(response) // 用invoke调用函数
                } else if (response.has("message")) {
                    val errorMsg = response.getString("message")
                    mOnVolleyError?.invoke(errorMsg) ?: Toast.makeText(mContext, errorMsg, Toast.LENGTH_LONG).show()
                }
                mOnVolleyEnd?.invoke() // 调用结束回调
            },
            Response.ErrorListener { volleyError: VolleyError ->
                Log.d("GetVolleyError", volleyError.message.toString())
                val errorMessage: String = if (volleyError is NetworkError || volleyError is AuthFailureError) {
                    "No Internet…"
                } else {
                    "Undefined error"
                }
                mOnVolleyError?.invoke(errorMessage) ?: Toast.makeText(mContext, errorMessage, Toast.LENGTH_LONG).show()
                mOnVolleyEnd?.invoke()
            })
        Volley.newRequestQueue(mContext).add(request)
    }

    init {
        getDataVolley()
    }
}

简化后的调用方式

现在你就可以用Lambda表达式来调用,完全符合你想要的写法:

// 三个回调都传的情况
GetVolley(
    this,
    url,
    { response -> parseResponse(response) },
    { error -> showError(error) },
    { /* 这里写onEnd的逻辑 */ }
)

// 部分回调为null的情况(比如只传成功和失败回调)
GetVolley(
    this,
    url,
    { parseResponse(it) }, // 可以用it代替参数名更简洁
    { showError(it) },
    null
)

// 甚至可以省略大括号(当Lambda只有一行代码时)
GetVolley(this, url, ::parseResponse, ::showError, null)

方案二:将接口改为Kotlin的fun interface(SAM接口)

如果你想保留原有的接口定义,可以把三个接口都改成fun interface(Kotlin 1.4+支持),这样Kotlin会自动支持SAM转换,允许你用Lambda来代替匿名内部类:

修改后的接口代码

fun interface OnVolleySuccess {
    fun onSuccess(response: JSONObject)
}

fun interface OnVolleyError {
    fun onError(error: String)
}

fun interface OnVolleyEnd {
    fun onEnd()
}

调用方式

此时你的GetVolley类不需要修改构造函数,直接用Lambda调用即可:

GetVolley(
    this,
    url,
    { parseResponse(it) },
    { showError(it) },
    null
)

两种方案都能实现你想要的简化效果,方案一更直接,方案二则保留了原有的接口结构,你可以根据自己的需求选择~

内容的提问来源于stack exchange,提问作者Shuhratjon Jumaev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 19:27:43