使用 Retrofit 方法更具表现力的方式
Use Retrofit methods more expressive way
我想让 void enqueue(Callback<T> callback);
方法调用代码块更具表现力,这是我通常使用的
request.enqueue(object : Callback<MyModel> {
override fun onFailure(call: Call<MyModel>?, t: Throwable?) {
//
}
override fun onResponse(call: Call<MyModel>?, response: Response<MyModel>?) {
//
}
})
我想要的意思是,以更简洁的方式更改此代码块并删除那些 override、object、Callback 关键字并执行类似的操作:
request.enqueue({throwable, response -> })
我认为可以使用扩展和高阶函数以某种方式改进它。有谁知道怎么做?
你可以做的是这个(这是 Java 因为我不太了解 Kotlin,但应该非常相似):
public class CallbackWrapper<T> implements Callback<T> {
private Wrapper<T> wrapper;
public CallbackWrapper(Wrapper<T> wrapper) {
this.wrapper = wrapper;
}
public void onFailure(Call<T> call, Throwable t) {
wrapper.onResult(t, null);
}
public void onResponse(Call<T> call, Response<T> response) {
wrapper.onResult(null, response);
}
public static interface Wrapper<T> {
void onResult(Throwable t, Response<T> response);
}
}
您可以用作:
call.enqueue(new CallbackWrapper((throwable, reponse) - > {...}));
更新kotlin解决方案:
基于 this,CallBackWrapper
看起来像这样:
typealias wrapper<T> = (t: Throwable?, response: Response<T>?) -> Unit
class CallbackWrapper<T>(val wrapper: wrapper<T>) : Callback<T> {
override fun onFailure(call: Call<T>?, t: Throwable?) = wrapper.invoke(t,null)
override fun onResponse(call: Call<T>?, response: Response<T>?) = wrapper.invoke(null, response)
}
和Java一样使用。
给定以下函数:
fun <T> callback(fn: (Throwable?, Response<T>?) -> Unit): Callback<T> {
return object : Callback<T> {
override fun onResponse(call: Call<T>, response: retrofit2.Response<T>) = fn(null, response)
override fun onFailure(call: Call<T>, t: Throwable) = fn(t, null)
}
}
您可以像这样将它与 Retrofit 一起使用:
request.enqueue(callback({ throwable, response ->
response?.let { callBack.onResponse(response.body() ?: RegisterResponse()) }
throwable?.let { callBack.onFailed(throwable.message!!) })
或者,您可以定义其他版本的回调:
fun <T> callback2(success: ((Response<T>) -> Unit)?, failure: ((t: Throwable) -> Unit)? = null): Callback<T> {
return object : Callback<T> {
override fun onResponse(call: Call<T>, response: retrofit2.Response<T>) { success?.invoke(response) }
override fun onFailure(call: Call<T>, t: Throwable) { failure?.invoke(t) }
}
}
可以这样使用:
request.enqueue(callback2(
{ r -> callBack.onResponse(r.body()) },
{ t -> callBack.onFailed(t.message) }))
我在 Call
上使用了一个扩展函数来编写一个富有表现力的通用 enqueue
方法。
fun<T> Call<T>.onEnqueue(actOnSuccess: (Response<T>) -> Unit, actOnFailure: (t: Throwable?) -> Unit) {
this.enqueue(object: Callback<T> {
override fun onFailure(call: Call<T>?, t: Throwable?) {
actOnFailure(t)
}
override fun onResponse(call: Call<T>?, response: Response<T>) {
actOnSuccess(response)
}
})
}
这可以用作:
request.onEnqueue {
actOnSuccess = {
doOnSuccess()
}
actOnFailure = {
doOnFailure()
}
}
在 actOnSuccess 和 actOnFailure 代码块中,it
应分别引用 Response
和 Throwable
对象,并且可以是相应地杠杆化。例如,在 actOnFailure 代码块中 -
actOnFailure = {
doOnFailure()
//it.message //'it' refers to the Throwable object.
}
您可以像这样创建一个扩展函数
inline fun <T> Call<T>.addEnqueue(
crossinline onSuccess: (response: Response<T>) -> Unit = { response: Response<T> -> },
crossinline onFail: (t: Throwable) -> Unit = { throwable: Throwable ->}
):Callback<T> {
val callback = object : Callback<T> {
override fun onFailure(call: Call<T>, t: Throwable) {
onFail(t)
}
override fun onResponse(call: Call<T>, response: Response<T>) {
onSuccess(response)
}
}
enqueue(callback)
return callback
}
并在您的 activity 或片段
中像这样使用它
service?.fetchUser()?.addEnqueue(
onSuccess = {
doOnSuccess(it)
},
onFail = {
doOnFail(it)
}
)
这就是我使用扩展函数和 class
的方式
fun<T> Call<T>.enqueue(callback: CallBackKt<T>.() -> Unit) {
val callBackKt = CallBackKt<T>()
callback.invoke(callBackKt)
this.enqueue(callBackKt)
}
class CallBackKt<T>: Callback<T> {
var onResponse: ((Response<T>) -> Unit)? = null
var onFailure: ((t: Throwable?) -> Unit)? = null
override fun onFailure(call: Call<T>, t: Throwable) {
onFailure?.invoke(t)
}
override fun onResponse(call: Call<T>, response: Response<T>) {
onResponse?.invoke(response)
}
}
那你就可以这样使用了
request.enqueue {
onResponse = {
// do
}
onFailure = {
// do
}
}
我想让 void enqueue(Callback<T> callback);
方法调用代码块更具表现力,这是我通常使用的
request.enqueue(object : Callback<MyModel> {
override fun onFailure(call: Call<MyModel>?, t: Throwable?) {
//
}
override fun onResponse(call: Call<MyModel>?, response: Response<MyModel>?) {
//
}
})
我想要的意思是,以更简洁的方式更改此代码块并删除那些 override、object、Callback 关键字并执行类似的操作:
request.enqueue({throwable, response -> })
我认为可以使用扩展和高阶函数以某种方式改进它。有谁知道怎么做?
你可以做的是这个(这是 Java 因为我不太了解 Kotlin,但应该非常相似):
public class CallbackWrapper<T> implements Callback<T> {
private Wrapper<T> wrapper;
public CallbackWrapper(Wrapper<T> wrapper) {
this.wrapper = wrapper;
}
public void onFailure(Call<T> call, Throwable t) {
wrapper.onResult(t, null);
}
public void onResponse(Call<T> call, Response<T> response) {
wrapper.onResult(null, response);
}
public static interface Wrapper<T> {
void onResult(Throwable t, Response<T> response);
}
}
您可以用作:
call.enqueue(new CallbackWrapper((throwable, reponse) - > {...}));
更新kotlin解决方案:
基于 this,CallBackWrapper
看起来像这样:
typealias wrapper<T> = (t: Throwable?, response: Response<T>?) -> Unit
class CallbackWrapper<T>(val wrapper: wrapper<T>) : Callback<T> {
override fun onFailure(call: Call<T>?, t: Throwable?) = wrapper.invoke(t,null)
override fun onResponse(call: Call<T>?, response: Response<T>?) = wrapper.invoke(null, response)
}
和Java一样使用。
给定以下函数:
fun <T> callback(fn: (Throwable?, Response<T>?) -> Unit): Callback<T> {
return object : Callback<T> {
override fun onResponse(call: Call<T>, response: retrofit2.Response<T>) = fn(null, response)
override fun onFailure(call: Call<T>, t: Throwable) = fn(t, null)
}
}
您可以像这样将它与 Retrofit 一起使用:
request.enqueue(callback({ throwable, response ->
response?.let { callBack.onResponse(response.body() ?: RegisterResponse()) }
throwable?.let { callBack.onFailed(throwable.message!!) })
或者,您可以定义其他版本的回调:
fun <T> callback2(success: ((Response<T>) -> Unit)?, failure: ((t: Throwable) -> Unit)? = null): Callback<T> {
return object : Callback<T> {
override fun onResponse(call: Call<T>, response: retrofit2.Response<T>) { success?.invoke(response) }
override fun onFailure(call: Call<T>, t: Throwable) { failure?.invoke(t) }
}
}
可以这样使用:
request.enqueue(callback2(
{ r -> callBack.onResponse(r.body()) },
{ t -> callBack.onFailed(t.message) }))
我在 Call
上使用了一个扩展函数来编写一个富有表现力的通用 enqueue
方法。
fun<T> Call<T>.onEnqueue(actOnSuccess: (Response<T>) -> Unit, actOnFailure: (t: Throwable?) -> Unit) {
this.enqueue(object: Callback<T> {
override fun onFailure(call: Call<T>?, t: Throwable?) {
actOnFailure(t)
}
override fun onResponse(call: Call<T>?, response: Response<T>) {
actOnSuccess(response)
}
})
}
这可以用作:
request.onEnqueue {
actOnSuccess = {
doOnSuccess()
}
actOnFailure = {
doOnFailure()
}
}
在 actOnSuccess 和 actOnFailure 代码块中,it
应分别引用 Response
和 Throwable
对象,并且可以是相应地杠杆化。例如,在 actOnFailure 代码块中 -
actOnFailure = {
doOnFailure()
//it.message //'it' refers to the Throwable object.
}
您可以像这样创建一个扩展函数
inline fun <T> Call<T>.addEnqueue(
crossinline onSuccess: (response: Response<T>) -> Unit = { response: Response<T> -> },
crossinline onFail: (t: Throwable) -> Unit = { throwable: Throwable ->}
):Callback<T> {
val callback = object : Callback<T> {
override fun onFailure(call: Call<T>, t: Throwable) {
onFail(t)
}
override fun onResponse(call: Call<T>, response: Response<T>) {
onSuccess(response)
}
}
enqueue(callback)
return callback
}
并在您的 activity 或片段
中像这样使用它 service?.fetchUser()?.addEnqueue(
onSuccess = {
doOnSuccess(it)
},
onFail = {
doOnFail(it)
}
)
这就是我使用扩展函数和 class
的方式fun<T> Call<T>.enqueue(callback: CallBackKt<T>.() -> Unit) {
val callBackKt = CallBackKt<T>()
callback.invoke(callBackKt)
this.enqueue(callBackKt)
}
class CallBackKt<T>: Callback<T> {
var onResponse: ((Response<T>) -> Unit)? = null
var onFailure: ((t: Throwable?) -> Unit)? = null
override fun onFailure(call: Call<T>, t: Throwable) {
onFailure?.invoke(t)
}
override fun onResponse(call: Call<T>, response: Response<T>) {
onResponse?.invoke(response)
}
}
那你就可以这样使用了
request.enqueue {
onResponse = {
// do
}
onFailure = {
// do
}
}