java - Retrofit v2 Call.cancel() 是否删除回调?

标签 java android retrofit2 okhttp

我已阅读Retrofit v2 API Spec在从自定义改造接口(interface)返回的 Call 类上调用 cancel() 方法应将传入的 Callback 设置为 null。

cancel() is a no-op after the response has been received. In all other cases the method will set any callbacks to null (thus freeing strong references to the enclosing class if declared anonymously)

浏览代码,我看不到调用取消时回调被显式设置为 null。我可以看到 OkHttpCall 中引用了回调类(尽管没有显式存储)。调用cancel将依次调用RealCall类上的cancel,该类负责取消的Http端,但不关心AsyncCall类中存储的回调(它被放入Dispatcher类中的readyAsyncCalls和runningAsyncCalls队列中)。对我来说是不熟悉的代码,所以我可能会遗漏一些东西。

有人可以自信地确认在我的调用对象上调用 cancel() 将删除对我传入的回调的引用,这样我就不会泄漏内存吗?

简化的代码示例:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    final Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    api = retrofit.create(Api.class);
}

@Override
public void onStart() {
    super.onStart();
    call = api.getPokedex();
    call.enqueue(new Callback<Pokedex>() {
        @Override
        public void onResponse(Call<Pokedex> call, Response<Pokedex> response) {
            populate(response.body());
        }

        @Override
        public void onFailure(Call<Pokedex> call, Throwable t) {
            error(t.getMessage());
        }
    });
}

@Override
public void onStop() {
    call.cancel();
    super.onStop();
}

最佳答案

如果您根据文档 Call#Cancel 取消调用,则不会删除对 CallBack 的引用。

  /**
   * Cancel this call. An attempt will be made to cancel in-flight calls, and if the call has not
   * yet been executed it never will be.
   */
  void cancel();

反正Call取消后,会调用CallBack,即onFailure方法。

public interface Callback<T> {
  /**
   * Invoked when a network exception occurred talking to the server or when an unexpected
   * exception occurred creating the request or processing the response.
   */
  void onFailure(Call<T> call, Throwable t);
}

在代码中测试 Call#isCanceled() 的最简单方法。

 @Override
        public void onFailure(Call<Pokedex> call, Throwable t) {
            Log.w(TAG, "Call is canceled: " + call.isCancelled());
            error(t.getMessage());
        }

关于java - Retrofit v2 Call.cancel() 是否删除回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35685635/

相关文章:

android - Auth.GOOGLE_SIGN_IN_API 不能与 Games.API 一起使用

java - 为什么我在使用 Retrofit 和 GSON 转换器映射的对象属性上得到空值?

android - 如何在 Kotlin 中处理两个不同的 Retrofit 响应?

java - Spring Security 在 Spring Boot 中检索用户名时提供 Null 身份验证

Java Swing BorderLayout 使一个区域不可调整大小

java - 防止多个用户执行相同的操作

android - 如何在android中实现在 fragment 内显示和隐藏 fragment

java - 枚举值不与 switch 中的枚举进行比较

使用 URL Scheme 启动应用程序时的 Android Back Stack

java - Android Retrofit - 发送动态数量的 POST 参数