2015-08-27 94 views
165

我想表明在从SD卡ImageView的已经被存储在位图图像。运行后,我的应用程序崩溃和获取的OutOfMemoryError错误:安卓:java.lang.OutOfMemoryError:无法分配与2097152个免费字节23970828字节分配和2MB直到OOM

(java.lang.OutOfMemoryError: Failed to allocate a 23970828 byte allocation with 2097152 free bytes and 2MB until OOM)

我不知道为什么它的内存不足。我认为我的图像尺寸非常大,所以我试图改变它。

Iterator<String> it = imageArray.iterator(); 
while (it.hasNext()) { 
    Object element = it.next(); 
    String objElement = element.toString(); 
    Log.e("objElement ", " = " + objElement); 
    final ImageView imageView = new ImageView (getContext()); 
    final ProgressBar pBar = new ProgressBar(getContext(), null, 
              android.R.attr.progressBarStyleSmall); 
    imageView.setTag(it); 
    pBar.setTag(it); 

    imageView.setImageResource(R.drawable.img_placeholder); 
    pBar.setVisibility(View.VISIBLE); 

    if (objElement.endsWith(mp3_Pattern)) { 
    Log.e("Mp3 ", " ends with "); 
    pBar.setVisibility(View.GONE); 
    imageView.setImageResource(R.drawable.audio_control); 
    } 
    if (objElement.endsWith(png_Pattern)) { 
    Bitmap bitmap = BitmapFactory.decodeFile(objElement); 
    int size = Math.min(bitmap.getWidth(), bitmap.getHeight()); 
    int x = (bitmap.getWidth() - size)/2; 
    int y = (bitmap.getHeight() - size)/2; 
    Bitmap bitmap_Resul = Bitmap.createBitmap(bitmap, x, y, size, size); 
    Log.e("bitmap_Resul "," = "+ bitmap_Resul); 

    if (bitmap_Resul != bitmap) { 
     bitmap.recycle(); 
    } 
    imageView.setImageBitmap(bitmap_Resul); 
    Log.e("png_Pattern ", " ends with "); 
    Log.e(" bitmap "," = " + bitmap); 
    } 

    holder.linearLayout.addView(imageView); 
    holder.linearLayout.addView(pBar); 

日志猫信息:

08-27 14:11:15.307 1857-1857/? E/AndroidRuntime﹕ FATAL EXCEPTION: main 
    Process: com.example.tazeen.classnkk, PID: 1857 
    java.lang.OutOfMemoryError: Failed to allocate a 23970828 byte allocation with 2097152 free bytes and 2MB until OOM 
      at dalvik.system.VMRuntime.newNonMovableArray(Native Method) 
      at android.graphics.Bitmap.nativeCreate(Native Method) 
      at android.graphics.Bitmap.createBitmap(Bitmap.java:812) 
      at android.graphics.Bitmap.createBitmap(Bitmap.java:789) 
      at android.graphics.Bitmap.createBitmap(Bitmap.java:709) 
      at android.graphics.Bitmap.createBitmap(Bitmap.java:634) 
      at com.example.tazeen.classnkk.AllPosts_Page$MyListAdapter.getView(AllPosts_Page.java:357) 
      at android.widget.AbsListView.obtainView(AbsListView.java:2347) 
      at android.widget.ListView.makeAndAddView(ListView.java:1864) 
      at android.widget.ListView.fillDown(ListView.java:698) 
      at android.widget.ListView.fillFromTop(ListView.java:759) 
      at android.widget.ListView.layoutChildren(ListView.java:1659) 
      at android.widget.AbsListView.onLayout(AbsListView.java:2151) 
      at android.view.View.layout(View.java:15671) 
      at android.view.ViewGroup.layout(ViewGroup.java:5038) 
      at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703) 
      at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557) 
      at android.widget.LinearLayout.onLayout(LinearLayout.java:1466) 
      at android.view.View.layout(View.java:15671) 
      at android.view.ViewGroup.layout(ViewGroup.java:5038) 
      at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579) 
      at android.widget.FrameLayout.onLayout(FrameLayout.java:514) 
      at android.view.View.layout(View.java:15671) 
      at android.view.ViewGroup.layout(ViewGroup.java:5038) 
      at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703) 
      at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557) 
      at android.widget.LinearLayout.onLayout(LinearLayout.java:1466) 
      at android.view.View.layout(View.java:15671) 
      at android.view.ViewGroup.layout(ViewGroup.java:5038) 
      at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579) 
      at android.widget.FrameLayout.onLayout(FrameLayout.java:514) 
      at android.view.View.layout(View.java:15671) 
      at android.view.ViewGroup.layout(ViewGroup.java:5038) 
      at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2086) 
      at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1843) 
      at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061) 
      at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885) 
      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) 
      at android.view.Choreographer.doCallbacks(Choreographer.java:580) 
      at android.view.Choreographer.doFrame(Choreographer.java:550) 
      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) 
      at android.os.Handler.handleCallback(Handler.java:739) 
      at android.os.Handler.dispatchMessage(Handler.java:95) 
      at android.os.Looper.loop(Looper.java:135) 
      at android.app.ActivityThread.main(ActivityThread.java:5257) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:372) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698) 
+1

检查图像的像素,宽度不得超过1440和高度2560,通过这样做,它不会显示** OutOfMemoryError ** –

+0

@PankajLilan你在哪里找到这些值(1440 X 2560)?来自android文档的任何引用? – Lijo

回答

249

的OutOfMemoryError是Android上最常见的问题发生,而尤其是与位图处理。当由于缺少内存空间而无法分配对象并且垃圾收集器无法释放一些空间时,Java虚拟机(JVM)会抛出此错误。

正如Aleksey所提到的,您可以在清单文件android:hardwareAccelerated="false",android:largeHeap="true"中添加以下实体,它将适用于某些环境。

<application 
    android:allowBackup="true" 
    android:hardwareAccelerated="false" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:largeHeap="true" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 

你肯定应该读一些机器人会开发概念的,特地在这里:Displaying Bitmaps Efficiently

阅读所有5个主题,并再次重写代码。如果它仍然不起作用,我们将很高兴看到你在教程材料中做了什么错误。

在这里,SOF

Android: BitmapFactory.decodeStream() out of memory with a 400KB file with 2MB free heap

How to solve java.lang.OutOfMemoryError trouble in Android

Android : java.lang.OutOfMemoryError

java.lang.OutOfMemoryError

Solution for OutOfMemoryError: bitmap size exceeds VM budget

一些这些类型的错误,可能的答案3210

编辑:从@cjnash的意见

对于任何人,仍然有崩溃后,他们加入这一行,尽量坚持你的图像到RES /绘制-xhdpi /文件夹,而不是你RES /绘制/和它可能解决你的问题。

+1

可以你请张贴你最终如何解决问题?因为我有同样的问题...其实你可以在你的清单中添加这行android:hardwareAccelerated =“false”,android:largeHeap =“true”它适用于某些情况,但要注意代码的另一部分可以与此争论...... –

+0

所以我有一张地图,我想在这里显示多段线。我想要在这些多段线上显示箭头以显示方向。箭头通过拍摄朝上箭头的图像,旋转并粘贴为标记来实现。我有大约500个这些标记。当我更改缩放比例时,我将删除所有标记,然后创建适合缩放级别的较新标记。然而旧的不是垃圾收集,所以经过几次放大和缩小后,我得到了OutOfMemoryError。 Bitmap的'LruCache'没有帮助。我还有什么可以优化的? –

+1

添加后,应用导航变得非常缓慢。 –

62

你尝试过在应用程序中加入给你的表现? android:largeHeap="true"

这样

<application 
     android:name=".ParaseApplication" 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" 
     android:largeHeap="true" > 
+7

我试过用这个android:largeHeap =“true”,但得到相同的错误 – androidTag

+1

尝试压缩你的图像,然后才能使用这个链接https://tinyjpg.com/ – TSG

+0

你也可以用这个网站压缩png – TSG

7

调整大小您的设置来的ImageView这样的前像:

Bitmap.createScaledBitmap(_yourImageBitmap, _size, _size, false); 

其中size是ImageView的实际大小。您可以通过测量达到大小:

imageView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 

,并使用下一大小imageView.getMeasuredWidth()imageView.getMeasuredHeight()scaling

+0

我试过用这个android:largeHeap =”true“但是得到相同的错误 – androidTag

+0

为什么这不一定会工作(使用私人应用程序存储): 将位图放置在res/drawable /中可以给出相同的错误,但不会每次都发生,将相同位图放入res/drawable-xhdpi /将不再有错误 因此一个答案,它自己不正确 – CmosBattery

14

对我来说,问题是我的.png文件被解压缩成内存中真正巨大的位图,因为图像的尺寸非常大(即使文件大小很小)。

所以修复是简单地调整图像大小:)

+0

这是正确的解决方案,因为我第一次尝试上面的解决方案,但在应用'android:hardwareAccelerated =“false”'后,一些动画,如布局阴影不起作用。问题解决了谢谢!+1对于这个提示! – Kaushal28

+0

这解决了我的问题。 nk你@petrus –

5

使用滑翔图书馆和覆盖大小尺寸更小;

Glide.with(mContext).load(imgID).asBitmap().override(1080, 600).into(mImageView); 
20

其实你可以在你的清单,这些线路android:hardwareAccelerated="false"android:largeHeap="true"它正在为某些情况下增加,但是要注意的代码的另一部分可以用此来争论。

<application 
    android:allowBackup="true" 
    android:hardwareAccelerated="false" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:largeHeap="true" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 
+1

没有工作,它崩溃时使用相同的错误,当使用Bitmap.createBitmap – NarendraJi

+0

@King对不起(我也花了一些时间来解决这个问题,它是为我工作。但它只是其中一种方式...有很多不同的方法 –

+0

@MrNarendra你怎么解决它呢? – Shruti

2

我已经解决了这个问题,通过调整图像的大小来减小尺寸。我正在使用xamarin表单。减小PNG图像的大小解决了问题。

0

如果上传图像,请尝试降低图像质量,这是位图的第二个参数。这是我的情况的解决方案。以前它是90,然后我尝试了60(因为它现在在下面的代码中)。

Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream); 
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
finalBitmap.compress(Bitmap.CompressFormat.JPEG,60,baos); 
byte[] b = baos.toByteArray(); 
7

这应该工作

BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inSampleSize = 8; 

mBitmapInsurance = BitmapFactory.decodeFile(mCurrentPhotoPath,options); 
+0

这个答案解决了我的问题。 – Thirumalvalavan

3

我有以下错误

"E/art: Throwing OutOfMemoryError "Failed to allocate a 47251468 byte allocation with 16777120 free bytes and 23MB until OOM"

加入android:largeHeap="true" AndroidManifest.xml中后,然后我摆脱所有的错误

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/guruji" 
    android:label="@string/app_name" 
    android:supportsRtl="true" 
    android:largeHeap="true" 
    android:theme="@style/AppTheme"> 
+2

对我的情况没有效果 –

0

我是一名Android开发新手,但我希望我的解决方案能够帮助,它完美适用于我的情况。我使用Imageview并将其背景设置为“src”,因为我试图制作一个框架动画。我得到了同样的错误,但当我试图代码这工作

int ImageID = this.Resources.GetIdentifier(questionPlay[index].Image.ToLower(), "anim", PackageName); 
      imgView.SetImageResource(ImageID); 
      AnimationDrawable animation = (AnimationDrawable)imgView.Drawable; 
      animation.Start(); 
      animation.Dispose(); 
1

我也有问题。

与上面大多数人一样。 问题是由巨大的图像造成的。

只是调整一些图像的大小, 并且无需更改任何代码。

2
Bitmap image =((BitmapDrawable)imageView1.getDrawable()).getBitmap(); 

ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream(); 

image.compress(Bitmap.CompressFormat.JPEG,50/100,byteArrayOutputStream); 

50/100如果使用100,则原始分辨率可以停止应用程序内存不足。

如果50或小于100,这将是50%或小于100分辨率,这将避免内存不足的问题

0

尝试最简单的一种。也许你的应用程序崩溃,因为你的图像大小(以MB为单位)太大,所以它不会为此分配空间。所以在绘制粘贴您的图像之前刚刚通过任何浏览器软件减小体积,或者如果你是从画廊在运行时不是将其保存压缩您的位图前摄像图像。 它为我工作。绝对会为你的。

1

在一些情况下(在循环中例如操作)垃圾收集器比你的代码慢。您可以使用一个helper method from this answer等待垃圾回收器

0

我就遇到了这个问题,当我移动到一个新的活动的时候没有杀了我原有的业务。我finish();

Intent goToMain = new Intent(this,MainActivity.class); 
    startActivity(goToMain); 
    finish(); 
2

Soluton固定它试试这个在您的清单文件,并使用滑翔图书馆

编译 'com.github.bumptech.glide:滑翔:3.7.0'

**Use Glide Library and Override size to less size;** 

if (!TextUtils.isEmpty(message.getPicture())) { 
      Glide.with(mContext).load(message.getPicture()) 
        .thumbnail(0.5f) 
        .crossFade() 
        .transform(new CircleTransform(mContext)) 
        .diskCacheStrategy(DiskCacheStrategy.ALL) 
        .into(holder.imgProfile); 
     } 

安卓硬件加速= “假”

机器人:largeHeap = “真”

<application 
    android:allowBackup="true" 
    android:hardwareAccelerated="false" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:largeHeap="true" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 

使用这个库

compile 'com.github.bumptech.glide:glide:3.7.0' 

其工作快乐编码

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapShader; 
import android.graphics.Canvas; 
import android.graphics.Paint; 

import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; 
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation; 


public class CircleTransform extends BitmapTransformation { 
    public CircleTransform(Context context) { 
     super(context); 
    } 

    @Override 
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) { 
     return circleCrop(pool, toTransform); 
    } 

    private static Bitmap circleCrop(BitmapPool pool, Bitmap source) { 
     if (source == null) return null; 

     int size = Math.min(source.getWidth(), source.getHeight()); 
     int x = (source.getWidth() - size)/2; 
     int y = (source.getHeight() - size)/2; 

     // TODO this could be acquired from the pool too 
     Bitmap squared = Bitmap.createBitmap(source, x, y, size, size); 

     Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888); 
     if (result == null) { 
      result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); 
     } 

     Canvas canvas = new Canvas(result); 
     Paint paint = new Paint(); 
     paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP)); 
     paint.setAntiAlias(true); 
     float r = size/2f; 
     canvas.drawCircle(r, r, r, paint); 
     return result; 
    } 

    @Override 
    public String getId() { 
     return getClass().getName(); 
    } 
} 
0

这为我工作:刚刚从绘制文件夹移动图像绘制-hdpi。

0

Issue : Failed to allocate a 37748748 byte allocation with 16777120 free bytes and 17MB until OOM

解决方案: 1.open清单文件 2的内部应用程序标签只需添加下面两行

android:hardwareAccelerated="false" 
android:largeHeap="true" 

例子:

<application 
     android:allowBackup="true" 
     android:hardwareAccelerated="false" 
     android:largeHeap="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:roundIcon="@mipmap/ic_launcher_round" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 
0

我发现在图像'drawable'文件夹将被转换为高清手机上更大的图像。例如,一个200k的图像将被重新采样到更高的分辨率,如800k或32000k。我必须自己发现这一点,并且迄今还没有看到有关堆内存陷阱的文档。为了防止出现这种情况,我将所有内容都放在drawable-nodpi文件夹中(除了使用基于特定设备堆的BitmapFactory中的“选项”外)。我不能让我的应用程序臃肿多个绘制文件夹的大小,特别是屏幕DEFS的范围现在是如此巨大。棘手的是工作室现在没有具体指明“绘制-nodpi”文件夹,例如在项目视图,它只是显示了一个“绘制”文件夹。如果你不小心,当你删除一个图像到这个文件夹中的工作室,也不会真正得到投进绘制-nodpi:

Careful here 'backgroundtest' did not actually go to drawable-nodpi and will 
be resampled higher, such as 4x or 16x of the original dimensions for high def screens. 

enter image description here

请务必点击下到nodpi文件夹,因为项目视图不会像以前那样单独显示所有可绘制的文件夹,因此不会立即明显地看到它出错了。工作室重新在某些点上香草“绘制”我很久以前就删除了它后:

enter image description here

0

你必须改变物体的大小绘制。这对于android来说显得太大了。例如如果您正在设置图像尝试使用较少像素的图像。这个对我有用。 谢谢。 :)

相关问题