【问题标题】:Custom Implementation of Callback for Retrofit in KotlinKotlin 中改造回调的自定义实现
【发布时间】:2018-12-20 17:11:51
【问题描述】:

我最近开始使用 Kotlin 进行我的 android 开发,并且遇到了一些小问题,通过使用文档我能够解决这些问题,但是使用 Retrofit Callback 实现我遇到了一个问题。我在 Java 中使用的 Retrofit 回调有一个自定义实现:

public abstract class RemoteCallback<T> implements Callback<T> {
@Override
public final void onResponse(Call<T> call, Response<T> response) {

    switch (response.code()) {
        case HttpsURLConnection.HTTP_OK:
        case HttpsURLConnection.HTTP_CREATED:
        case HttpsURLConnection.HTTP_ACCEPTED:
        case HttpsURLConnection.HTTP_NOT_AUTHORITATIVE:
            if (response.body() != null) {
                onSuccess(response.body());
            }
            break;
        case HttpURLConnection.HTTP_UNAUTHORIZED:
            onUnauthorized();
            break;
        default:
            onFailed(new Throwable("Default " + response.code() + " " + response.message()));
    }
}

@Override
public final void onFailure(Call<T> call, Throwable t) {
    onFailed(t);
}

public abstract void onSuccess(T responseBody);

public abstract void onUnauthorized();

public abstract void onFailed(Throwable throwable);}

我在 Kotlin 项目中使用了相同的类,它反过来将 java 代码转换为 kotlin 代码

abstract class RemoteCallback<T> : Callback<T> {
override fun onResponse(call: Call<T>, response: Response<T>) {

    when (response.code()) {
        HttpsURLConnection.HTTP_OK,
        HttpsURLConnection.HTTP_CREATED,
        HttpsURLConnection.HTTP_ACCEPTED,
        HttpsURLConnection.HTTP_NOT_AUTHORITATIVE ->
            if (response.body() != null)
            onSuccess(response.body())
        HttpURLConnection.HTTP_UNAUTHORIZED -> onUnauthorized()
        else -> onFailed(Throwable("Default " + response.code() + " " + response.message()))
    }
}

override fun onFailure(call: Call<T>, t: Throwable) {
    onFailed(t)
}

abstract fun onSuccess(responseBody: T)

abstract fun onUnauthorized()

abstract fun onFailed(throwable: Throwable)}

问题是当我调用 onSucess(response.body()) 时,因为它说“智能转换为 'T' 是不可能的,因为 'response.body()' 是一个复杂的表达式” 请指导我如何解决它

【问题讨论】:

  • 你尝试使用Any类型
  • 与 java 相比,在 kotlin 中处理泛型是棘手且困难的。所以你需要手动投射,这会给出unchecked cast 警告。试试onSuccess(response.body() as T)。但是,我会推荐一种替代方法,使用带有 reified T 的扩展

标签: android kotlin retrofit retrofit2


【解决方案1】:

您将Nullable 值作为参数发送到NonNull 函数。因此,您遇到了这个问题。你可以这样做:

interface RemoteCallback<T> : Callback<T> {
    override fun onResponse(call: Call<T>?, response: Response<T>?) {
        when (response?.code()) {
            HttpsURLConnection.HTTP_OK,    
            HttpsURLConnection.HTTP_CREATED,
            HttpsURLConnection.HTTP_ACCEPTED,
            HttpsURLConnection.HTTP_NOT_AUTHORITATIVE ->
                response.body()?.apply { onSuccess(this) }
            HttpURLConnection.HTTP_UNAUTHORIZED -> onUnauthorized()
            else -> onFailed(Throwable("Default " + response?.code() + " " + response?.message()))
        }
    }

    override fun onFailure(call: Call<T>?, t: Throwable?) {
        // handle error mechanism
        t?.apply { onFailed(this) }    
    }
    fun onSuccess(responseBody: T)
    fun onUnauthorized()
    fun onFailed(throwable: Throwable)
}

或者,您可以只使用onSuccess(responseBody: T?),您的代码应该可以工作

【讨论】:

    【解决方案2】:

    我的项目有一个非常相似的实现。如下尝试

    abstract class RemoteCallback: Callback<ResponseBody> {
        override fun onFailure(call: Call<ResponseBody>?, t: Throwable?) {
            onFailed(t)
        }
    
        override fun onResponse(call: Call<ResponseBody>?, response: Response<ResponseBody>?) {
            when (response.code()) {
                HttpsURLConnection.HTTP_OK,
                HttpsURLConnection.HTTP_CREATED,
                HttpsURLConnection.HTTP_ACCEPTED,
                HttpsURLConnection.HTTP_NOT_AUTHORITATIVE ->
                    if (response.body() != null)
                    onSuccess(response.body())
                HttpURLConnection.HTTP_UNAUTHORIZED -> onUnauthorized()
                else -> onFailed(Throwable("Default " + response.code() + " " + response.message()))
            }
        }
    
        abstract fun onUnauthorized()
    
        abstract fun onFailed(throwable: Throwable)
    }
    

    对我来说很好

    【讨论】:

      猜你喜欢
      • 2018-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-08
      • 2020-09-08
      • 1970-01-01
      • 1970-01-01
      • 2018-01-29
      相关资源
      最近更新 更多