Andorid Volley框架加载图片OOM问题分析

一、Volley框架简介

在这之前,我们在程序中需要和网络通信的时候,大体使用的东西莫过于AsyncTaskLoader,HttpURLConnection,AsyncTask,HTTPClient(Apache)等,Google 在2013年的I/O大会 上,发布了Volley。Volley是Android平台上的网络通信库,能使网络通信更快,更简单,更健壮。

Volley提供了JsonObjectRequest、JsonArrayRequestStringRequest等Request形式

JsonObjectRequest:返回JSON对象

JsonArrayRequest:返回JsonArray。

StringRequest:返回String,这样可以自己处理数据,更加灵活

另外可以继承自定义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内存分析工具,找出引起内存没有释放的原因

发现是context没有释放,导致内存泄露,继续分析,找到没有引起GC的保持该引用的地方

找到最短的GC path,发现是Volley中德CacheDispacher保持了context的引用,导致没有引起GC释放内存。

但是volley框架内的东西怎么会引起这种问题?

首先想到在onDestroy中取消掉没有加载完的request。但是没有效果

google 了半天,终于在stackoverflow上找到了答案,大概的意思就是说,初始化RequestQueue的时候尽量使用全局的Context也就是ApplicationContext。

否则的话没有Activity都要维护一个volley请求队列以及分发线程、请求线程和缓存线程。

这样就会导致,在volley框架的内部保持了一个Activity的context引用,也就是说,当我们的Activity的生命周期结束了之后,volley中可能还有没走完的子线程中依然保留该context的引用,导致无法内存回收。

四、解决方法

首先,我们要保持项目中唯一一个Volley的RequestQueue,使用单例模式来实现

public class SingleRequestQueue {

    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;
    }
}

在统一一个类中处理网络请求。

另外,看到网上评论说当加载大的网络图片的时候不建议使用Volley,我用的是UniversalImageLoader。

推荐一篇文章讲解Android 中Context。点这里

总结:

之前一直没有遇到context上下文内存泄露的问题,这个问题很好地弥补了这方面的空白

通过这个问题的分析解决,加深了内存泄露的分析思路,同时也巩固了MAT内存分析工具的使用方法。

时间: 2024-10-09 15:06:15

Andorid Volley框架加载图片OOM问题分析的相关文章

Android利用Volley框架加载网络图片

Volley框架是在Google I/O 2013上Volley发布的,目的是使Android平台上的网络通信库,能使网络通信更快,更简单,更健壮.我们也简单了解下Volley引入的背景,在Volley出现以前,我们可能面临如下的问题,比如要在ListView或是GridView中加载数量较多的图片时:先在ListAdapter#getView()里开始图像的读取,再通过AsyncTask等机制使用HttpURLConnection从服务器去的图片资源,然后在AsyncTask#onPostEx

android 加载图片oom若干方案小结

本文根据网上提供的一些技术方案加上自己实际开发中遇到的情况小结. 众所周知,每个Android应用程序在运行时都有一定的内存限制,限制大小一般为16MB或24MB(视手机而定).一般我们可以通过获取当前线程的可运行内存来判断,比如系统分给当前运行内存只有16M,而你的图片就有16M,这肯定会oom的. 相关知识介绍 1.颜色模型 常见的颜色模型有RGB.YUV.CMYK等,在大多数图像API中采用的都是RGB模型,Android也是如此:另外,在Android中还有包含透明度Alpha的颜色模型

Android之批量加载图片OOM问题解决方案

一.OOM问题出现的场景和原因 一个好的app总少不了精美的图片,所以Android开发中图片的加载总是避免不了的,而在加载图片过程中,如果处理不当则会出现OOM的问题.那么如何彻底解决这个问题呢?本文将具体介绍这方面的知识. 首先我们来总结一下,在加载图片过程中出现的OOM的场景无非就这么几种: 1.  加载的图片过大 2.  一次加载的图片过多 3.  以上两种情况兼有 那么为什么在以上场景下会出现OOM问题呢?实际上在API文档中有着明确的说明,出现OMM的主要原因有两点: 1.移动设备会

Android开发解决加载图片OOM问题(非常全面 兼顾4.0以下系统)(by 星空武哥)

转载请标明:http://blog.csdn.net/lsyz0021/article/details/51295402 我们项目中经常会加载图片,有时候如果加载图片过多的话,小则导致程序很卡,重则OOM导致App挂了,今天翻译https://developer.Android.com/training/displaying-bitmaps/index.html,学习Google高效加载大图片的方法. 图片有各种形状和大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小.比如说系统图片库

Picasso图片框架加载图片 使用及缓存问题

项目中用的Picasso 框架 ,加载图片.使用很方便 而且缓存机制非常强大. 正常使用我们可以这样直接调用,我把方法写到一个util里面了. 调用代码如下: PicassoUtil.displayImage(context, Constants.U_IMG_URL, R.drawable.default, iv_icon); Util工具类 import java.io.File; import android.content.Context; import android.text.Text

Android使用开源框架加载图片

Android开发时,有时候需要们来加载网络图片,我们可以通过api的方式进行加载,但是前几天做的时候,发现了一个优秀的开源框架,可以帮助我们非常简单便捷的进行图片的加载,所以记录一下. 我所用的是: android-smart-image-view 在github上的地址是:https://github.com/loopj/android-smart-image-view,我们可以直接进行搜索,github对于我们程序员来说简直是宝库啊,一定要能够擅长应用. 下载下来后,我们把其目录下的src

从加载图片OOM说起

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.big); Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.big); Bitmap bitmap3 = BitmapFactory.decodeResource(getResources(), R.drawable.big); 创建三个 Bitmap,并且

Android利用Volley异步加载数据(JSON和图片)完整示例

Android利用Volley异步加载数据(JSON和图片)完整示例 MainActivity.java package cc.testvolley; import org.json.JSONObject; import android.app.Activity; import android.app.ProgressDialog; import android.graphics.Bitmap; import android.os.Bundle; import android.support.v

使用UIL(Universal-Image-Loader)异步加载图片

概要: Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是实现可重复使用的异步图像加载.缓存和显示.所以,如果你的程序里需要这个功能的话,使用它,因为已经封装好了一些类和方法.其实,写一个这方面的程序还是比较麻烦的,要考虑多线程,缓存,内存溢出等很多方面. 功能介绍: A:多线程图片加载:          B:灵活更改ImageLoader的基本配置,包括最大线程数.缓存方式.图片显示选项等:          C:图片异步加载缓存机制,包括内