首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我应该担心内存泄漏和在Android中使用WeakReference和Volley吗?

我应该担心内存泄漏和在Android中使用WeakReference和Volley吗?
EN

Stack Overflow用户
提问于 2014-10-28 09:44:07
回答 3查看 2.2K关注 0票数 7

在阅读了this article之后,我开始思考Volley的内存泄漏问题。通常,用Volley实现的侦听器对外部类(活动)有一个隐式或显式的引用。例如:

代码语言:javascript
复制
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
        url, null, 
        new Response.Listener<JSONObject>() {
            @Override 
            public void onResponse(JSONObject response) {

                updateLayout(); 
            } 
        }

在这种情况下,有一个隐式引用...或者,我可能想创建一个自定义的JsonObjectRequest来内部化响应处理,并且需要在其构造函数中传入对调用活动的引用。

现在,假设我启动了一个web请求,但在响应返回之前,我离开了启动该请求的活动。据我所知,JsonObjectRequest对象将保留对我的活动的引用,并防止它被垃圾收集。

-Am如果我理解正确的话,这是一种合理的恐惧吗?

-Does排污库会自动处理这个吗?

如果我正在创建一个自定义的JsonObjectRequest并传入一个“-If”(对活动的引用),我需要为该活动创建一个WeakReference吗?

EN

回答 3

Stack Overflow用户

发布于 2015-05-23 00:22:15

基于对volley代码的查看,调用cancel并不能真正避免内存泄漏,因为引用永远不会被清除,并且引用并不弱。调用cancel只能避免Volley将响应传递给侦听器。

我对这个问题的解决方案是自己克隆和修改这个库。

  • 的解决方案之一是将基本ErrorListener中的基本Request.java引用设置为弱引用。类似地,可以对JsonRequest.java.
  • The中的侦听器执行同样的操作,其他解决方案可以在调用cancel时手动清除引用。在cancel()内部,将mErrorListener和mListener设置为null。但是,使用此解决方案时,您必须从字段声明中删除final修饰符,否则将不允许将引用设置为null。

希望这能有所帮助。

票数 5
EN

Stack Overflow用户

发布于 2015-06-18 16:16:05

我在使用volley时遇到过内存泄漏,就像你写here.everytime I new a new listener一样。

我使用leakcanary来检测泄漏。

当我读到您的文章http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html,并使用WeakReference进行活动和回调接口(我自己定制)时,它得到了解决。

我使用截击作为单例。

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2016-09-29 00:05:49

我参加这个聚会可能晚了一年,但我只是想出了一个解决这个问题的方法。这就是它:

代码语言:javascript
复制
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 && activityWeakReference.get()!=null,以避免在活动不存在时崩溃。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26599636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档