Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/228.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:java.lang.OutOfMemoryError:无法分配23970828字节的分配,该分配包含2097152个可用字节和2MB,直到OOM_Android_Android Bitmap - Fatal编程技术网

Android:java.lang.OutOfMemoryError:无法分配23970828字节的分配,该分配包含2097152个可用字节和2MB,直到OOM

Android:java.lang.OutOfMemoryError:无法分配23970828字节的分配,该分配包含2097152个可用字节和2MB,直到OOM,android,android-bitmap,Android,Android Bitmap,我想在已存储的sd卡的图像视图中显示位图图像。运行后,我的应用程序崩溃,并且出现OutOfMemoryError错误: (java.lang.OutOfMemoryError:无法分配23970828字节的分配,其中2097152个可用字节和2MB直到OOM) 我不知道,也不知道为什么会忘了。我认为我的图像尺寸很大,所以我试图改变它 Iterator<String> it = imageArray.iterator(); while (it.hasNext()) { Object

我想在已存储的sd卡的图像视图中显示位图图像。运行后,我的应用程序崩溃,并且出现OutOfMemoryError错误:

(java.lang.OutOfMemoryError:无法分配23970828字节的分配,其中2097152个可用字节和2MB直到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);

您是否尝试将其添加到应用程序下的清单中<代码>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" >

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">

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

下面是SOF中这些类型错误的一些可能答案

编辑:来自@cjnash的评论


对于添加此行后仍发生崩溃的任何人,请尝试将图像粘贴到res/drawable xhdpi/文件夹而不是res/drawable/文件夹中,这将解决此问题,然后再设置为ImageView,如下所示:

Bitmap.createScaledBitmap(_yourImageBitmap, _size, _size, false);
其中size是ImageView的实际大小。您可以通过测量以下各项达到尺寸:

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

使用next size
imageView.getMeasuredWidth()
imageView.getMeasuredHeight()
进行
缩放

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


因此,解决方法是简单地调整图像的大小:)

使用滑动库
并将大小覆盖为较小的大小

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

实际上,您可以在清单中添加以下行:
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">


我已通过将图像大小调整为较小的大小来解决此问题。我用的是xamarin形式。减小PNG图像的大小解决了问题。

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

这应该行得通

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

 mBitmapSampled = BitmapFactory.decodeFile(mCurrentPhotoPath,options);
我犯了以下错误

“E/art:抛出OfMemoryError”分配47251468字节失败 分配16777120个可用字节和23MB,直到OOM“

在android manifest.xml中添加
android:largeHeap=“true”
之后,我消除了所有错误

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

我是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();
我也有这个问题

与上面大多数其他人一样。 这个问题是由巨大的图像引起的

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

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分辨率,因此这将防止内存不足问题

尝试最简单的方法。可能是因为图像大小(MB)导致应用程序崩溃太大,因此无法为此分配空间。因此,在将图像粘贴到drawable之前,请使用任何查看器软件缩小图像的大小,或者如果您在运行时从gallery拍摄图像,请在保存之前压缩位图。
它对我有效。对你肯定有效。

在某些情况下(例如,循环中的操作)垃圾收集器比你的代码慢。你可以使用to等待垃圾收集器

当我转到一个新活动时没有终止我的旧活动时,我遇到了这个问题。我用
finish();


解决方案在清单文件中尝试此方法并使用Glide库

编译'com.github.bumptech.glide: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);
        } 
android:hardwareAccelerated=“false”

android:largeHeap=“true”

它的工作愉快的编码

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

这对我很有用:只需将图像从可绘制文件夹移动到可绘制hdpi即可

问题:无法使用16777120分配37748748字节分配 在OOM之前释放字节和17MB

解决方案: 1.打开清单文件 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">

我发现在高清手机上,“drawable”文件夹中的图像将被转换为更大的图像。例如,200k图像将被重新采样为更高的分辨率,如800k或3200K。我必须自己发现这一点,到目前为止还没有看到此堆内存陷阱的文档。为了防止这种情况,我将所有内容都放在drawabl中e-nodpi文件夹(除了根据特定设备堆在BitmapFactory中使用“选项”之外)。我不能让我的应用程序因多个可绘制文件夹而变得臃肿,尤其是现在屏幕定义的范围如此之大。棘手的是,studio现在没有在项目视图中明确指出“可绘制nodpi”文件夹,它只是
<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();
    }
}
 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">
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.
 android:hardwareAccelerated="false"
    android:largeHeap="true"
    android:allowBackup="true"
 dexOptions {
        incremental true
        javaMaxHeapSize "4g"
        preDexLibraries true
        dexInProcess = true
    }
stream = activity.getContentResolver().openInputStream(uri);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;

bitmap = BitmapFactory.decodeStream(stream, null, options);
int Height = bitmap.getHeight();
int Width = bitmap.getWidth();
enter code here
int newHeight = 1000;
float scaleFactor = ((float) newHeight) / Height;
float newWidth = Width * scaleFactor;

float scaleWidth = scaleFactor;
float scaleHeight = scaleFactor;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
resizedBitmap= Bitmap.createBitmap(bitmap, 0, 0,Width, Height, matrix, true);
bitmap.recycle();
Last but not the least....

Try Method One:

Simple Add these lines of code in the gradle file

dexOptions {
        incremental true
        javaMaxHeapSize "4g"
     }

Example:

android {
    compileSdkVersion XX
    buildToolsVersion "28.X.X"

    defaultConfig {
        applicationId "com.example.xxxxx"
        minSdkVersion 14
        targetSdkVersion 19
    }

dexOptions {
        incremental true
        javaMaxHeapSize "4g"
     }
}

*******************************************************************

Method Two:

Add these two lines of code in manifest file...

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

Example:

<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:hardwareAccelerated="false"
        android:largeHeap="true"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

It will Work for sure any of these cases.....
fun resizeBitmap(source: Bitmap): Bitmap {
      val maxResolution = 1000    //edit 'maxResolution' to fit your need
      val width = source.width
      val height = source.height
      var newWidth = width
      var newHeight = height
      val rate: Float

            if (width > height) {
                if (maxResolution < width) {
                    rate = maxResolution / width.toFloat()
                    newHeight = (height * rate).toInt()
                    newWidth = maxResolution
                }
            } else {
                if (maxResolution < height) {
                    rate = maxResolution / height.toFloat()
                    newWidth = (width * rate).toInt()
                    newHeight = maxResolution
                }
            }
            return Bitmap.createScaledBitmap(source, newWidth, newHeight, true)
 }