Android:java.lang.OutOfMemoryError: Failed to allocate a 23970828 byte allocation with 2097152 free bytes and 2MB until OOM
Android:java.lang.OutOfMemoryError: Failed to allocate a 23970828 byte allocation with 2097152 free bytes and 2MB until OOM
我想在 ImageView 中显示已存储的 sd 卡中的 Bitmap 图像。在 运行 之后,我的应用程序崩溃并出现 OutOfMemoryError 错误:
(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)
您是否尝试过将此添加到应用程序下的清单中? 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 中最常见的问题,尤其是在处理位图时。当由于内存不足 space 而无法分配对象时,Java 虚拟机 (JVM) 会抛出此错误,而且垃圾收集器无法释放一些 space.
如 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 开发人员概念,尤其是此处:Displaying Bitmaps Efficiently
阅读所有 5 个主题并再次重写您的代码。如果它仍然不起作用,我们将很高兴看到您在教程中做错了什么 material。
这里是 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
编辑:来自@cjnash
的评论
对于添加此行后仍然崩溃的任何人,请尝试将您的图像粘贴到您的 res/drawable-xhdpi/ 文件夹而不是您的 res/drawable/ ,这应该可以解决此问题
在设置为 ImageView 之前调整你的图像:
Bitmap.createScaledBitmap(_yourImageBitmap, _size, _size, false);
其中大小是 ImageView 的实际大小。您可以通过测量达到尺码:
imageView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
并使用下一个尺寸 imageView.getMeasuredWidth()
和 imageView.getMeasuredHeight()
用于 scaling
。
对我来说,问题是我的 .png 文件在内存中被解压缩为一个非常大的位图,因为图像的尺寸非常大(即使文件大小很小)。
所以解决方法是简单地调整图像大小:)
使用Glide Library并将大小覆盖为更小的大小;
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(因为它现在在下面的代码中)。
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: Throwing OutOfMemoryError "Failed to allocate a 47251468 byte
allocation with 16777120 free bytes and 23MB until 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">
我是 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 为单位)太大,因此它没有为此分配 space。因此,在将图像粘贴到可绘制对象之前,只需通过任何查看器软件减小尺寸,或者如果您在 运行 时间从图库中获取图像,那么在保存之前压缩您的位图。
它对我有用。绝对适合你。
在某些情况下(例如循环中的操作)垃圾收集器比您的代码慢。您可以使用 helper method from this answer 来 等待垃圾收集器 。
我 运行 在转向新的 activity 时没有杀死旧的 activity 时遇到了这个问题。我用 finish();
修复了它
Intent goToMain = new Intent(this,MainActivity.class);
startActivity(goToMain);
finish();
解决方案在您的清单文件中尝试这个并使用 Glide Library
编译'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"
<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();
}
}
这对我有用:只需将图像从 drawable 文件夹移动到 drawable-hdpi。
Issue : Failed to allocate a 37748748 byte allocation with 16777120
free bytes and 17MB until OOM
解决方案:
1.open 你的清单文件
2. 在application tag里面添加下面两行
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' 之外)。我不能让我的应用程序因多个可绘制文件夹而变得臃肿,尤其是现在屏幕定义的范围如此之大。棘手的是,studio 现在并没有在项目视图中具体指明 'drawable-nodpi' 文件夹,它只显示一个 'drawable' 文件夹。如果你不小心,当你在工作室中将图像拖放到这个文件夹时,它实际上不会被拖放到 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.
一定要在对话框中向下点击 nodpi 文件夹,因为项目视图不会像以前那样单独显示所有可绘制文件夹,所以不会立即明显看出它走错了.在我很久以前删除它之后,Studio 在某个时候为我重新创建了原版 'drawable':
您必须更改可绘制对象的大小。它太大 android 无法显示。例如如果您正在设置图像,请尝试使用较少像素的图像。这个对我有用。
谢谢。 :)
您的应用程序崩溃是因为您的图像大小(以 MB 或 KB 为单位)太大,因此它没有为此分配 space。因此,在将图像粘贴到可绘制对象之前,只需减小尺寸即可。
或
您可以在 Manifest.xml
的应用程序标签中添加关注
android:hardwareAccelerated="false"
android:largeHeap="true"
android:allowBackup="true"
添加本应用后不会崩溃
- 始终在应用程序中使用较小尺寸的图像。
- 如果你在应用中添加大尺寸图片,你应该添加上面的语法,但应用大小会增加。
添加后我的问题解决了
dexOptions {
incremental true
javaMaxHeapSize "4g"
preDexLibraries true
dexInProcess = true
}
在 Build.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();
然后在Application标签中,添加large heap size="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. select 图片资源
3. Select 图标类型
4.给图标起个名字
5. Select 资产类型图片
6. Trim 你的形象
单击下一步并完成。在您的 xml 或源代码中,只需引用图像,该图像现在将根据资产类型 selected 位于布局或 mipmap 文件夹中。错误将消失。
将此添加到应用程序下的清单中? android:largeHeap="true"
我真的不建议像这样编辑清单
android:hardwareAccelerated="false" , android:largeHeap="true"
这些选项会导致您的应用的动画效果不流畅。此外 'liveData' 或更改您的本地数据库(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:
Image Compression. I am using this website
2:
Convert images to mdpi,hdpi, xhdpi, xxhdpi, xxxhdpi. I am using this
webiste
不要删除 android:largeHeap="true"!
使 android:hardwareAccelerated="false"
变得 activity 具体。希望这可以解决冻结问题和动画问题。像这样...
<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>
我想在 ImageView 中显示已存储的 sd 卡中的 Bitmap 图像。在 运行 之后,我的应用程序崩溃并出现 OutOfMemoryError 错误:
(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)
您是否尝试过将此添加到应用程序下的清单中? 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 中最常见的问题,尤其是在处理位图时。当由于内存不足 space 而无法分配对象时,Java 虚拟机 (JVM) 会抛出此错误,而且垃圾收集器无法释放一些 space.
如 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 开发人员概念,尤其是此处:Displaying Bitmaps Efficiently
阅读所有 5 个主题并再次重写您的代码。如果它仍然不起作用,我们将很高兴看到您在教程中做错了什么 material。
这里是 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
编辑:来自@cjnash
的评论对于添加此行后仍然崩溃的任何人,请尝试将您的图像粘贴到您的 res/drawable-xhdpi/ 文件夹而不是您的 res/drawable/ ,这应该可以解决此问题
在设置为 ImageView 之前调整你的图像:
Bitmap.createScaledBitmap(_yourImageBitmap, _size, _size, false);
其中大小是 ImageView 的实际大小。您可以通过测量达到尺码:
imageView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
并使用下一个尺寸 imageView.getMeasuredWidth()
和 imageView.getMeasuredHeight()
用于 scaling
。
对我来说,问题是我的 .png 文件在内存中被解压缩为一个非常大的位图,因为图像的尺寸非常大(即使文件大小很小)。
所以解决方法是简单地调整图像大小:)
使用Glide Library并将大小覆盖为更小的大小;
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(因为它现在在下面的代码中)。
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: Throwing OutOfMemoryError "Failed to allocate a 47251468 byte allocation with 16777120 free bytes and 23MB until 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">
我是 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 为单位)太大,因此它没有为此分配 space。因此,在将图像粘贴到可绘制对象之前,只需通过任何查看器软件减小尺寸,或者如果您在 运行 时间从图库中获取图像,那么在保存之前压缩您的位图。 它对我有用。绝对适合你。
在某些情况下(例如循环中的操作)垃圾收集器比您的代码慢。您可以使用 helper method from this answer 来 等待垃圾收集器 。
我 运行 在转向新的 activity 时没有杀死旧的 activity 时遇到了这个问题。我用 finish();
Intent goToMain = new Intent(this,MainActivity.class);
startActivity(goToMain);
finish();
解决方案在您的清单文件中尝试这个并使用 Glide Library
编译'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"
<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();
}
}
这对我有用:只需将图像从 drawable 文件夹移动到 drawable-hdpi。
Issue : Failed to allocate a 37748748 byte allocation with 16777120 free bytes and 17MB until OOM
解决方案: 1.open 你的清单文件 2. 在application tag里面添加下面两行
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' 之外)。我不能让我的应用程序因多个可绘制文件夹而变得臃肿,尤其是现在屏幕定义的范围如此之大。棘手的是,studio 现在并没有在项目视图中具体指明 'drawable-nodpi' 文件夹,它只显示一个 'drawable' 文件夹。如果你不小心,当你在工作室中将图像拖放到这个文件夹时,它实际上不会被拖放到 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.
一定要在对话框中向下点击 nodpi 文件夹,因为项目视图不会像以前那样单独显示所有可绘制文件夹,所以不会立即明显看出它走错了.在我很久以前删除它之后,Studio 在某个时候为我重新创建了原版 'drawable':
您必须更改可绘制对象的大小。它太大 android 无法显示。例如如果您正在设置图像,请尝试使用较少像素的图像。这个对我有用。 谢谢。 :)
您的应用程序崩溃是因为您的图像大小(以 MB 或 KB 为单位)太大,因此它没有为此分配 space。因此,在将图像粘贴到可绘制对象之前,只需减小尺寸即可。
或
您可以在 Manifest.xml
的应用程序标签中添加关注 android:hardwareAccelerated="false"
android:largeHeap="true"
android:allowBackup="true"
添加本应用后不会崩溃
- 始终在应用程序中使用较小尺寸的图像。
- 如果你在应用中添加大尺寸图片,你应该添加上面的语法,但应用大小会增加。
添加后我的问题解决了
dexOptions {
incremental true
javaMaxHeapSize "4g"
preDexLibraries true
dexInProcess = true
}
在 Build.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();
然后在Application标签中,添加large heap size="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. select 图片资源 3. Select 图标类型 4.给图标起个名字 5. Select 资产类型图片 6. Trim 你的形象 单击下一步并完成。在您的 xml 或源代码中,只需引用图像,该图像现在将根据资产类型 selected 位于布局或 mipmap 文件夹中。错误将消失。
将此添加到应用程序下的清单中? android:largeHeap="true"
我真的不建议像这样编辑清单
android:hardwareAccelerated="false" , android:largeHeap="true"
这些选项会导致您的应用的动画效果不流畅。此外 'liveData' 或更改您的本地数据库(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:
Image Compression. I am using this website
2:
Convert images to mdpi,hdpi, xhdpi, xxhdpi, xxxhdpi. I am using this webiste
不要删除 android:largeHeap="true"!
使 android:hardwareAccelerated="false"
变得 activity 具体。希望这可以解决冻结问题和动画问题。像这样...
<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>