AndoridVolley框架加载图片OOM问题分析 - 新闻资讯 - 云南小程序开发|云南软件开发|云南网站建设-昆明葵宇信息科技有限公司

159-8711-8523

云南网建设/小程序开发/软件开发

知识

不管是网站,软件还是小程序,都要直接或间接能为您产生价值,我们在追求其视觉表现的同时,更侧重于功能的便捷,营销的便利,运营的高效,让网站成为营销工具,让软件能切实提升企业内部管理水平和效率。优秀的程序为后期升级提供便捷的支持!

您当前位置>首页 » 新闻资讯 » 技术分享 >

AndoridVolley框架加载图片OOM问题分析

发表时间:2020-10-19

发布人:葵宇科技

浏览次数:41


一、Volley框架简介
在这之前,我们在法度榜样中须要和收集通信的时刻,大年夜体应用的器械莫过于AsyncTaskLoader,HttpURLConnection,AsyncTask,HTTPClient(Apache)等,Google 在2013年的I/O大年夜会 上,宣布了Volley。Volley是Android平滔喔赡收集通信库,能使收集通信更快,更简单,更结实。
Volley供给了JsonObjectRequest、JsonArrayRequestStringRequest等Request情势
public class SingleRequestQueue {
JsonObjectRequest:返回JSON对象
JsonArrayRequest:返回JsonArray。
别的可以持续自定义Request。
二、VOlley引起的OOM项目顶用到Volley下载收集图片,在回调中获取到bitmap做响应地操作。
       ImageRequest imageRequest = new ImageRequest(url+"--"+ bmWidth+"x"+bmWidth+".png",                new Response.Listener<Bitmap>() {                    @Override                    public void onResponse(Bitmap response) {                        initViewWithBitmap(response);                    }                }, 0, 0, Bitmap.Config.RGB_565, getImageError);        mQueue.add(imageRequest);
起先发明在这个界面操作偶先强关问题,抓到log看下是 outofmemory引起的。
因为该界面用到bitmap的处所比较多,所以在onDestoy()办法中手动释放bitmap。
用内存查看器不雅察该界面的内存情况,发明每次进入退出后,内存并没有完全释放,大年夜概每次都来6M阁下
经由过程这个问题的分析解决,加深了内存泄漏的分析思路,同时也巩固了MAT内存分析对象的应用办法。
三、问题分析
对象:MAT内存分析对象
用MAT内存分析对象,找出引起内存没有释放的原因
    private static RequestQueue mQueue;

    private SingleRequestQueue(Context context) {
        mQueue = Volley.newRequestQueue(context);
    }

    public static synchronized RequestQueue getRequestQueue(Context context){
        if (mQueue == null){
            new SingleRequestQueue(context.getApplicationContext());
        }
        return mQueue;
    }
}

[img]http://img.blog.csdn.net/20150106150626576?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGxnbGluZ2xvbmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

发明是context没有释放,导致内存泄漏,持续分析,找到没有引起GC的保持该引用的处所
[img]http://img.blog.csdn.net/20150106150629375?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGxnbGluZ2xvbmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

找到最短的GC path,发明是Volley中德CacheDispacher保持了context的引用,导致没有引起GC释放内存。
[img]http://img.blog.csdn.net/20150106150728109?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGxnbGluZ2xvbmc=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
在同一一个类中处理收集请求。

然则volley框架内的器械怎么会引起这种问题?
起首想到在onDestroy中撤消掉落没有加载完的request。然则没有效不雅
google 了半天,终于在stackoverflow上找到了谜底,大年夜概的意思就是说,初始化RequestQueue的时刻尽量应用全局的Context也就是ApplicationContext。
不然的话没有Activity都要保护一个volley请求队列以及分发线程、请求线程懈弛存线程。
如许就会导致,在volley框架的内部保持了一个Activity的context引用,也就是说,当我们的Activity的生命周期停止了之后,volley中可能还有没走完的子线程中依然保存该context的引用,导致无法内存收受接收。
四、解决办法
StringRequest:返回String,如许可以本身处理数据,加倍灵活
起首,我们要保持项目中独一一个Volley的RequestQueue,应用单例模式来实现

别的,看到网上评论说当加载大年夜的收集图片的时刻不建议应用Volley,我用的是UniversalImageLoader。
推荐一篇文┞仿讲解Android 中Context。点这里
总结:
之前一向没有碰到context高低文内存泄漏的问题,这个问题很好地弥补了这方面的空白

相关案例查看更多