BitmapFactory.decodeStream方法OutOfMemoryError 解决方法

    xiaoxiao2024-12-20  4

    OutOfMemory.CN技术专栏 ->  Java ->  OutOfMemoryError全攻略 -> Android BitmapFactory.decodeStream方法OutOfMemoryError 解决方法

    Android BitmapFactory.decodeStream方法OutOfMemoryError 解决方法

    更多 0 Android  OutOfMemoryError  java

    我的Android App在执行下面代码时出现了OutOfMemoryError异常

    image = BitmapFactory.decodeStream(assetManager.open(imgFilename));

    App执行到这一步就会出现OOM异常,异常信息如下:

    (...) 08-05 21:22:12.443: I/dalvikvm-heap(2319): Clamp target GC heap from 25.056MB to 24.000MB 08-05 21:22:12.443: D/dalvikvm(2319): GC_FOR_MALLOC freed <1K, 50% free 2709K/5379K, external 18296K/19336K, paused 58ms 08-05 21:22:14.513: D/dalvikvm(2319): GC_EXTERNAL_ALLOC freed <1K, 50% free 2709K/5379K, external 18296K/19336K, paused 101ms 08-05 21:22:14.903: I/dalvikvm-heap(2319): Clamp target GC heap from 25.073MB to 24.000MB 08-05 21:22:14.903: D/dalvikvm(2319): GC_FOR_MALLOC freed 0K, 50% free 2709K/5379K, external 18312K/19336K, paused 53ms 08-05 21:22:22.843: D/ddm-heap(2319): Heap GC request 08-05 21:22:22.963: I/dalvikvm-heap(2319): Clamp target GC heap from 25.073MB to 24.000MB 08-05 21:22:22.963: D/dalvikvm(2319): threadid=1: still suspended after undo (sc=1 dc=1) 08-05 21:22:22.963: D/dalvikvm(2319): GC_EXPLICIT freed 1K, 50% free 2710K/5379K, external 18312K/19336K, paused 116ms

    通过DDMS可以看到当时内存堆的使用情况

    Heap Size:  5.254 MBAllocated:  2.647 MBFree:   2.607 MB%Used:  50.38%#Objects    49,028

      

    只要指定到这一行就会出现OutOfMemoryError异常

    08-05 21:26:04.783: D/dalvikvm(2319): GC_EXTERNAL_ALLOC freed <1K, 50% free 2710K/5379K, external 18312K/19336K, paused 57ms 08-05 21:26:05.023: E/dalvikvm-heap(2319): 2097152-byte external allocation too large for this process. 08-05 21:26:05.163: I/dalvikvm-heap(2319): Clamp target GC heap from 25.073MB to 24.000MB 08-05 21:26:05.163: E/GraphicsJNI(2319): VM won't let us allocate 2097152 bytes 08-05 21:26:05.163: D/dalvikvm(2319): GC_FOR_MALLOC freed 0K, 50% free 2710K/5379K, external 18312K/19336K, paused 30ms 08-05 21:26:05.283: D/skia(2319): --- decoder->decode returned false

    在windows中可以看到图片文件的大小是小于400K的,而BitmapFactory.decodeStream()方法却要试图分配2M的内存。

    出现这个异常是因为Android类库在处理图片载入时不是很智能,我们还需要做一些额外的工作。

    我测试发现,Drawable.createFromStream方法要不BitmapFactory.decodeStream方法占用更多的内存。

    你可以通过修改图片的颜色模式(Color schema)来减少创建图片使用的内存量

    BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Config.RGB_565; Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);

    这个可以参考: http://developer.android.com/reference/android/graphics/Bitmap.Config.html

    你也可以通过加载一个缩放之后的图片,来减少创建图片时的内存分配量,但是需要注意图片缩放后可能会损失质量

    BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);

    可以参考: http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html 要动态设置图片的inSampleSize,需要先得到图片的尺寸。

    BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; bitmap = BitmapFactory.decodeStream(stream, null, options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; options.inJustDecodeBounds = false; // recreate the stream // make some calculation to define inSampleSize options.inSampleSize = ?; Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);

    你可以根据用户手机屏幕的大小来计算图片的尺寸,如下代码可以获得手机设备的尺寸。

    DisplayMetrics metrics = new DisplayMetrics(); ((Activity) activity).getWindowManager().getDefaultDisplay().getMetrics(metrics); int screenWidth = metrics.widthPixels; int screenHeight =metrics.heightPixels;
    转载请注明原文地址: https://ju.6miu.com/read-1294791.html
    最新回复(0)