我在Retrofit v2 API Spec中读到,在从自定义改造接口返回的 Call 类上调用 cancel() 方法应该将传入的 Callback 设置为 null。
cancel() 在收到响应后是无操作的。在所有其他情况下,该方法会将任何回调设置为 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();
}