如何在自定义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
相关产品推荐
相关产品推荐

