Android: . lang。OutOfMemoryError:未能分配23970828字节分配,2097152空闲字节和2MB直到OOM

我想显示位图图像在ImageView从sd卡已经存储。运行后,我的应用程序崩溃,并得到OutOfMemoryError错误:

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

日志猫信息:

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)
512597 次浏览

你试过把这个加到你的申请清单里吗?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">

你绝对应该阅读一些android开发者的概念,特别是这里:高效显示位图

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

这里有一些可能的答案,这些类型的错误在SOF

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

如何解决Android中的java.lang.OutOfMemoryError问题

Android: java.lang.OutOfMemoryError . outofmemoryerror

< a href = " https://stackoverflow.com/questions/20441644/java-lang-outofmemoryerror-bitmapfactory-decodestrpath " > java.lang.OutOfMemoryError < / >

内存溢出错误的解决方案:位图大小超过虚拟机预算

编辑:来自@ chjnash的评论

对于添加这一行后仍然有崩溃的任何人,尝试将图像粘贴到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));

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

对我来说,问题是我的.png文件被解压缩成内存中的一个非常大的位图,因为图像的维度非常大(尽管文件大小很小)。

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

使用滑翔图书馆和Override size减小大小;

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

我已经通过将图像大小调整到较低的大小来解决这个问题。我用的是沙玛林形式。减小PNG图像的大小解决了这个问题。

如果上传图片,请尝试降低图片质量,这是位图的第二个参数。这就是我案例中的解。以前是90,然后我尝试了60(正如下面的代码所示)。

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

这应该可以

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


mBitmapSampled = BitmapFactory.decodeFile(mCurrentPhotoPath,options);

我得到了下面的错误

"E/art: throws OutOfMemoryError "Failed to allocate a 47251468 byte . 分配16777120空闲字节和23MB直到OOM"

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

我是一个机器人开发的新手,但我希望我的解决方案有帮助,它在我的条件下完美工作。我使用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之前,只要减少大小的任何查看器软件,或者如果你是从图库在运行时比保存它压缩你的位图。 这对我很管用。

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

我遇到了这个问题,当我移动到一个新的活动时,我没有杀死我的旧活动。我用finish();修复了它

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

解决方案尝试在您的清单文件和使用滑翔库

编译的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);
}

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

使用这个库

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

这对我来说很有效:只需要将图像从可绘制文件夹移动到可绘制的hdpi。

问题:在16777120中分配37748748字节分配失败 释放字节和17MB直到OOM

< p >解决方案: 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或32000k。我必须自己发现这个问题,到目前为止还没有看到关于这个堆内存陷阱的文档。为了防止这种情况,我把所有东西都放在一个drawable-nodpi文件夹中(除了基于特定设备堆在BitmapFactory中使用“options”)。我不能让我的应用程序的大小因多个可绘制文件夹而膨胀,特别是现在屏幕defs的范围如此之大。棘手的事情是工作室现在没有特别指出'drawable-nodpi'文件夹在项目视图中,它只是显示一个'drawable'文件夹。如果你不小心,当你在studio中将图像放到这个文件夹中时,它实际上不会被放到drawable-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文件夹,因为项目视图不会像以前那样分别显示所有可绘制的文件夹,所以不会立即显示到错误的文件夹。在我很久以前删除了它之后,Studio在某个时候为我重新创建了香草“可绘制”:

enter image description here

你必须改变drawable中对象的大小。它太大了,android无法显示。例:如果你正在设置图像,请尝试像素更少的图像。这对我很管用。 谢谢。:) < / p >

你的应用程序崩溃,因为你的图像大小(MB或KB) 太大了,所以它没有分配空间。所以在将图像粘贴到drawable中之前,减小大小。

您可以在Manifest.xml的应用程序标签中添加Following

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

添加此应用程序后不会崩溃。

  • 在应用程序中总是使用较小尺寸的图像。
  • 如果你在应用程序中添加大尺寸的图像,你应该添加以上syntex,但应用程序大小将增加。

我的问题在添加后解决了

 dexOptions {
incremental true
javaMaxHeapSize "4g"
preDexLibraries true
dexInProcess = true
}

在构建。Gradle文件

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

然后在Appliaction标签中添加largeheapsize="true

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

使用像毕加索滑翔这样的图像加载库。使用这些库将在将来防止崩溃。

我猜你想用这个图像作为图标。正如Android告诉你的,你的图像太大了。你所需要做的就是缩放你的图像,这样Android就可以根据屏幕分辨率知道使用图像的大小和时间。要做到这一点,在Android Studio中: 1. 右键单击res文件夹, 2. 选择图像资产 3.选择图标类型 4. 给图标起一个名字 5. 在“资产类型”中选择“映像” 6. 修剪你的图片 单击下一步并完成。在你的xml或源代码只是参考图像,现在将位于布局或mipmap文件夹根据资产类型选择。

.错误将消失

把这个加到申请舱单上?android: largeHeap = " true "

我真的不建议像这样编辑清单

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

这些选项会导致应用程序的动画效果不流畅。此外,“liveData”或更改本地DB(Sqlite, Room)激活缓慢。这不利于用户体验。

所以我推荐RESIZE位图

下面是示例代码

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

如果android:largeHeap="true"不为你工作,那么

1:

图像压缩。我正在使用这个网站

2:

转换图像为mdpi,hdpi, xhdpi, xxhdpi, xxxhdpi。我在用这个 网路 < / p >

不要删除android:largeHeap="true"!

使android:hardwareAccelerated="false"是特定于活动的。希望,这可以解决冻结问题以及动画问题。像这样…

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true">
.
.
.
.
<activity android:name=".NavigationItemsFolder.GridsMenuActivityClasses.WebsiteActivity"
android:windowSoftInputMode="adjustPan"
android:hardwareAccelerated="false"/>
</application>