在阅读this article后,我开始考虑与Volley的内存泄漏。 通常,使用Volley实现的侦听器具有对外部类(活动)的隐式或显式引用。例如:
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
url, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
updateLayout();
}
}
在这种情况下有一个隐式引用...或者我可能想创建一个自定义JsonObjectRequest来内化响应处理,并且需要在其构造函数中传入对调用活动的引用。
现在让我说我开始一个Web请求,但在响应回来之前,我离开了启动请求的活动。根据我的理解,JsonObjectRequest对象将保留对我的活动的引用并防止它被垃圾收集。
- 我理解这一点,这是一种合理的恐惧吗?
- Volley图书馆会自动处理这个吗?
- 如果我正在创建一个自定义的JsonObjectRequest并传入一个&#34;这个&#34; (参考活动),我是否需要为活动创建一个WeakReference?
答案 0 :(得分:5)
根据查看凌空代码,调用cancel并不能真正避免内存泄漏,因为引用永远不会被清除,引用也不会很弱。调用取消只会避免Volley将响应传递给听众。
我对问题的解决方案必须自己克隆和修改库。
其中一个解决方案可以是将基础Request.java中的基本ErrorListener引用作为弱引用。类似地,可以对JsonRequest.java中的Listener进行相同的操作。
另一种解决方案是在取消被调用时手动清除引用。在cancel()内部,将mErrorListener和mListener设置为null。但是,使用此解决方案,您必须从字段声明中删除最终修饰符,否则您将无法将引用设置为null。
希望这有帮助。
答案 1 :(得分:2)
我在使用凌空时遇到了内存泄漏,就像你在这里写的那样。每次我都是新的听众。
我用泄漏检测泄漏。
当我读到您的文章http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html,并将WeakReference用于活动和回调界面(我自定义)时,它就解决了。
我用排球作为单身人士。
public interface VolleyCallback {
void onSuccess(JSONObject result);
void onFailed(String error);
}
private static class SListener implements Response.Listener<JSONObject> {
private final WeakReference<Activity> activityWeakReference;
private final WeakReference<VolleyCallback> callbackWeakReference;
public SListener(Activity activity, VolleyCallback callback) {
activityWeakReference = new WeakReference<Activity>(activity);
callbackWeakReference = new WeakReference<VolleyCallback>(callback);
}
@Override
public void onResponse(JSONObject jsonObject) {
Activity act = activityWeakReference.get();
VolleyCallback vc = callbackWeakReference.get();
if (act != null && vc != null) {
LogUtil.d(TAG, act.toString() + " " + jsonObject.toString());
something you need to do;
vc.onSuccess(jsonObject);
}
}
我也读了这个答案,How to use WeakReference in Java and Android development?,第二个答案给出了一个例子,就像你提供的文章一样。这很好。
答案 2 :(得分:1)
我可能迟到了一年,但我只想找到解决这个问题的方法。这是:
public interface VolleyCallback {
void onSuccess(JSONObject result);
void onFailed(String error);
}
private static class SListener implements VolleyCallback {
private final WeakReference<MainActivity> activityWeakReference;
public SListener(MainActivity activity, VolleyCallback callback) {
activityWeakReference = new WeakReference<>(activity);
}
@Override
void onSuccess(JSONObject result){
}
@Override
void onFailed(String error){
}
}
这里你可以使用activityWeakReference.get()来访问MainActivity的所有UI元素。
从http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html找到了这个。这样我们就不需要取消onStop()中的任何请求。请记得使用activityWeakReference.get().isFinishing
&amp;&amp; activityWeakReference.get()!=null
以避免在活动不存在时崩溃。