改造v2 Call.cancel()会删除回调吗?

时间:2016-02-28 17:13:56

标签: java android retrofit2 okhttp3

我已经在Retrofit v2 API Spec中读取了从自定义改装界面返回的Call类调用cancel()方法应该将传入的Callback设置为null。

  

取消()是收到回复后的无操作。在所有其他   在这种情况下,该方法会将任何回调设置为null(从而释放强大的   如果匿名声明,则引用封闭类)

通过代码我无法看到在调用cancel时将Callback显式设置为null。我可以看到OkHttpCall类中引用的回调(虽然没有明确存储)。调用cancel将依次调用取消对Realcall类的取消,该类负责取消的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();
}

1 个答案:

答案 0 :(得分:0)

未删除对CallBack的引用,如果您根据文档Call#Cancel

取消了呼叫
  /**
   * 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);
}

如果调用#isCanceled(),则是在代码中进行测试的最简单方法。

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