Volley静态回调侦听器上下文GCed

时间:2016-03-28 10:28:54

标签: java android memory-leaks android-volley

使用LeakCanary后,我发现我的应用程序中有很多泄漏,其中大部分是由于Volley的匿名回调监听器。所以我写了一个Util(下面)类,它使用静态回调和SessionEndedEvent来保持对WeakReference的引用和匿名回调。但是当我第一次打开应用程序时,即冷启动时,在提出请求后不久就会对上下文进行GC操作,但在热启动期间一切正常。此外,这仅适用于应用中的第一个活动。

任何可以正常工作的处理内存泄漏的替代方法也是受欢迎的。

Context

2 个答案:

答案 0 :(得分:1)

GC取决于许多正在发生的事情。一个可能的原因是,当您在冷启动后进行第一次请求时#39;你的app必须初始化各种自定义对象,片段,活动,视图缓存等,因此在增加堆之前需要内存,从而进行GC。

我建议的解决方案是改变你的架构。

1)似乎你保持对上下文的引用,但它从未使用过。放下它

2)你有Volley回调代表你需要传递的自定义回调,为什么不简单地使用你传递给相应请求的一组回调。

3)你WeekRef你的自定义回调,但你不能没有它们。周参考不是内存泄漏的最终解决方案。你必须找出为什么当你不需要时,裁判仍在那里。

所以,如果你在JsonCallback泄漏问题,StringCallback和ErrorCallback实现只是试图解决这个问题,而不是让链更长,并在最后切割它。

答案 1 :(得分:0)

感谢 djodjo 的回答,这有助于我找到解决方案

  • 始终使用addToRequestQueue(request, TAG)。这里TAG位是我们用来取消活动/片段/视图或其他任何内容的请求时

  • 我所做的是创建一个基本活动,并在该活动中添加所有此请求取消代码。这就是它的样子

    public abstract class BaseActivity extends AppCompatActivity {
    
        public final String tag;
    
        public BaseActivity() {
            super();
            tag = getClass().getSimpleName();
        }
    
        @Override
        protected void onDestroy() {
            App.getInstance().cancelRequests(tag);
            super.onDestroy();
        }
    
        protected <T> void addToRequestQueue(Request<T> request) {
            App.getInstance().addToRequestQueue(request, tag);
        }
    
    }
    

cancelRequests只是简单的代码

getRequestQueue().cancelAll(tag);

从此BaseActivity扩展您的活动并使用addToRequestQueue发出请求,这些请求会在您的活动被销毁时自动取消。对片段/对话框/其他任何事情做类似的事情。

如果您从其他任何不遵循生命周期的地方提出请求,请确保它不会绑定到任何Context,您就可以了。