`

Android—大图or多图加载解决方案(完美解决OOM问题)(转)

 
阅读更多
转自:http://www.2cto.com/kf/201407/321093.html

在开发应用的时候,很多时候都会涉及大量图片的加载和高精度图片的加载,这两种操作都是会导致应用程序OOM(OutOfMemory)的问题发生,合理的图片加载和图片内存管理就是必须解决的问题,以下将提供一个比较完善的技术方案,解决这两个问题。


首先,我们必须明确为什么会发生OOM(OutOfMemory)的问题,其原因就是因为在APP运行过程中,所使用的系统内存超出了当前APP的最大可用内存,就发生了OOM的问题。下面,我们来估算一下在一台中高档的手机上面,加载多少图片会导致OOM:假设系统分配给APP的最大可用内存为32M,加载一张512*512分辨率的图片,会占用2M的内存空间,这样,在APP中加载16张图片,就会出现OOM,事实上,当加载10张图片以上,都极容易导致OOM,因为APP运行中还是会占用内存的。(PS:图片占用内存计算:Android中Bitmap的默认加载使用ARGB_8888,每个像素会占用4byte,因为每个像素有两个Chanel,因此一个512*512的图片,无论什么格式,加载进入内存都占用512*512*4*2=2MB,所以,Android图片占用内存大小,只与图片的分辨率(像素)以及加载使用的色彩模式有关)


要解决OOM的问题,从两方面进行优化:1.合理加载资源 2.合理回收资源


合理加载资源

合理加载资源,既如果展示图片的ImageView只有128*96的像素大小,这时候把一张1024*768的图片完全加载到内存中,很明显是错误的行为。这个时候,就需要把要加载的图片进行压缩加载,就是合理地加载资源。

下面,来进行图片的压缩讲解,设置BitmapFactory.Options中inSampleSize的值就可以实现等比例压缩。比如我们有一张2048*1536像素的图片,将inSampleSize的值设置为4,就可以把这张图片压缩成512*384像素。原本加载这张图片需要占用26M的内存,压缩后就只需要占用1.5M了。下面的方法可以根据传入的宽和高,计算出合适的inSampleSize值:

public static int calculateInSampleSize(BitmapFactory.Options options,
        int reqWidth, int reqHeight) {
    // 源图片的高度和宽度
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;
    if (height > reqHeight || width > reqWidth) {
        // 计算出实际宽高和目标宽高的比率
        final int heightRatio = Math.round((float) height / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);
        // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
        // 一定都会大于等于目标的宽和高。
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }
    return inSampleSize;
}

计算出合适的缩放比例后,接着进行图片的实际压缩操作:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {
    // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);
    // 调用上面定义的方法计算inSampleSize值
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
    // 使用获取到的inSampleSize值再次解析图片
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}
经过以上的两步操作,即可实现合理的加载图片资源。

合理回收资源


合理回收资源,既对加载在内存中的图片资源进行合理的回收,避免因为不再使用的图片资源还留存在内存中的情况出现。而要实现合理回收资源,最核心的一个类就是:LruCache,这个类非常适用于保存图片内存,它的主要算法原理是把最近使用的对象用强引用存储在 LinkedHashMap 中,并且把最近最少使用的对象在缓存值达到预设定值之前从内存中移除。

下面给出具体的使用方法:

private LruCache<string, bitmap=""> mMemoryCache;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // 获取到可用内存的最大值,使用内存超出这个值会引起OutOfMemory异常。
    // LruCache通过构造函数传入缓存值,以KB为单位。
    int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
    // 使用最大可用内存值的1/8作为缓存的大小。
    int cacheSize = maxMemory / 8;
    mMemoryCache = new LruCache<string, bitmap="">(cacheSize) {
        @Override
        protected int sizeOf(String key, Bitmap bitmap) {
            // 重写此方法来衡量每张图片的大小,默认返回图片数量。
            return bitmap.getByteCount() / 1024;
        }
    };
}

public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
    if (getBitmapFromMemCache(key) == null) {
        mMemoryCache.put(key, bitmap);
    }
}

public Bitmap getBitmapFromMemCache(String key) {
    return mMemoryCache.get(key);
}</string,></string,>

只要确保整个APP的图片资源的使用,都是通过addBitmapToMemoryCache和getBitmapFromMemCache来进行,即可避免OOM的出现。
分享到:
评论

相关推荐

    Android加载网络图片与本地图片解决OOM问题

    "Android加载网络图片与本地图片解决OOM问题"这个主题旨在介绍如何有效地解决这些问题。 首先,我们需要理解为什么Android应用容易出现OOM。Android为每个应用程序分配了一定量的内存,当这个限制被超过时,系统会...

    Android加载大图片OOM异常解决

    Android 加载大图片 OOM 异常解决方案 在 Android 开发中,加载大图片是一个常见的问题,这可能会引发 OOM(Out of Memory)异常。OOM 异常是指应用程序试图分配超过系统可用内存的内存空间,从而导致应用程序崩溃...

    android加载大图避免oom

    本篇文章将详细讲解如何在Android中加载大图以避免OOM问题,参考自博客《Android加载大图避免OOM》。 1. OOM概述 OOM是Java虚拟机在分配内存时遇到的问题,当应用程序请求的内存超过系统可分配的阈值,系统无法...

    Android相册图片解决OOM问题

    2. **大图加载**:Android原生的Bitmap类在处理大图片时特别容易引发OOM。大图片直接加载到内存中会超出分配的内存限制,因此需要对图片进行适当的缩放处理。使用`BitmapFactory.Options`的`inSampleSize`参数可以...

    好用的单或多图片加载不会出现OOM

    总的来说,`Android-Universal-Image-Loader`是一个强大且灵活的图片加载解决方案,能够帮助开发者优化图片处理,避免OOM问题,提高应用性能。通过对`Android-Universal-Image-Loader-master`的详细学习和实践,...

    Android高级应用源码-加载本地图片,绝对不会出现OOM.zip

    "Android高级应用源码-加载本地图片,绝对不会出现OOM.zip"是一个针对这一问题的解决方案,它包含了如何在Android应用中加载本地图片而不引发内存溢出的示例代码。 首先,我们要理解为什么加载图片会引发OOM。在...

    Android高效加载大图、多图解决方案 有效避免程序OOM

    在Android开发中,高效加载大图和多图是至关重要的,因为如果不加以处理,这可能导致程序出现内存溢出(OOM)异常,严重影响用户体验。本文将详细介绍如何有效地避免此类问题。 首先,我们需要理解Android应用程序...

    android加载大量图片内存溢出的三种解决办法

    android加载大量图片内存溢出的三种解决办法

    android gridview 加载大量图片。无OOM

    综上所述,通过合理地使用图片缩略、延迟加载、缓存策略以及高效的图片加载库,我们可以有效地在Android GridView中加载大量图片,同时避免出现OOM问题。在实际开发中,应结合项目需求和性能测试,灵活运用这些策略...

    android防止oom的图片加载例子

    在Android开发中,由于系统对每个应用程序分配的内存有限,特别是在加载大图时,很容易触发“Out of Memory”(OOM)错误。这个错误是由于内存不足导致程序无法分配更多的内存空间,进而引发的运行时异常。针对这个...

    博客资源:ViewPager加载大量图片oom解决方案demo

    "博客资源:ViewPager加载大量图片oom解决方案demo" 这个标题表明了这是一个关于解决在Android应用中使用ViewPager展示大量图片时出现内存溢出(Out Of Memory,简称OOM)问题的实例教程。ViewPager是Android SDK中...

    android加载大图

    故事要从一场面试说起,当问到如何加载一个大图而不会发生OOM,这里有两种途径,一、降采样大图;二、局部加载大图 由于android内存的限制,andoid系统给每个应用分配的内存是有限的,当直接加载一个占用内存加大的...

    安卓gif加载解决oom

    在Android开发中,由于系统对内存管理的特性,开发者时常会遇到Out Of Memory(OOM)问题,尤其是在处理大量图片资源时,比如在ListView或者RecyclerView中加载动态图GIF。本篇将详细介绍如何解决Android中加载GIF...

    加载图片oom的解决

    在Android开发中,由于系统对每个应用程序分配的内存有限,加载大尺寸的图片可能会导致“Out Of Memory”(OOM)异常,从而影响应用的稳定性和性能。为了解决这个问题,我们需要掌握一些有效的策略来优化图片加载,...

    解决ViewFlipper加载多张图片出现OOM问题

    下面我们将深入探讨这个问题,并提供解决方案。 首先,我们需要理解`OOM`是如何发生的。在Android系统中,每个应用程序都有一定的内存限制。当应用消耗的内存超过这个限制时,系统就会抛出`OOM`异常,导致应用崩溃...

    Android解决图片OOM问题

    综上所述,解决Android图片OOM问题的关键在于合理地控制图片加载的大小、使用高效的图片加载库、实施适当的缓存策略以及优化图片资源本身。通过这些方法,我们可以在保证用户体验的同时,避免应用因内存不足而崩溃。

    Android高效加载大图、多图解决方案,有效避免程序OOM.docx

    总之,Android 应用在处理大量图片时,必须谨慎处理图片的加载和解码过程,以避免 OOM 异常。合理地压缩图片、选择合适的图片格式、利用图片加载库以及优化缓存策略,都是提高应用性能和用户体验的关键步骤。同时,...

    Android完美解决GridView异步加载图片和加载大量图片时出现Out Of Memory问题

    解决Android GridView中图片异步加载和OOM问题,需要结合异步处理、图片优化、缓存策略和视图复用等多方面的方法。使用合适的第三方库可以简化开发工作,但理解底层原理并结合实际情况进行优化是关键。合理管理内存...

    bitmap OOM的解决方案

    Bitmap OOM通常是由于加载过大或过多的图片资源导致内存溢出。以下是对这个问题的深入探讨和解决方案。 首先,理解Bitmap的工作原理至关重要。Bitmap对象在内存中占据较大的空间,因为它们存储了像素数据。Android...

    android 图片内存溢出(OOM)解决

    基本上解决了OOM问题 如果 方便可以直接引用BitmapManager类到 项目中使用 解决blog 地址http://www.cnblogs.com/liongname/articles/2345087.html

Global site tag (gtag.js) - Google Analytics