我已阅读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/