问题描述
我想在 ImageView 中显示已经存储的 sd 卡中的 Bitmap 图像.运行后,我的应用程序崩溃并收到 OutOfMemoryError 错误:
I want to show the Bitmap image in ImageView from sd card which is stored already. After run my application is crash and getting OutOfMemoryError error of:
(java.lang.OutOfMemoryError: Failed to allocate a 23970828 byte allocation with 2097152 free bytes and 2MB until OOM)
我不知道也不知道为什么它的内存不足.我认为我的图像尺寸非常大,所以我尝试更改它.
I have no idea or why its out of memory. I think my image size is very large so I tried to change it.
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)
推荐答案
OutOfMemoryError 是android 中最常见的问题,尤其是处理位图时.当由于内存空间不足而无法分配对象并且垃圾收集器无法释放一些空间时,Java 虚拟机 (JVM) 会抛出此错误.
OutOfMemoryError is the most common problem that occurs in android while especially dealing with bitmaps. This error is thrown by the Java Virtual Machine (JVM) when an object cannot be allocated due to lack of memory space and also, the garbage collector cannot free some space.
正如 Aleksey 提到的,您可以在清单文件中添加以下实体 android:hardwareAccelerated=false"
, android:largeHeap="true"
它适用于某些环境.
As mentioned by Aleksey, you can add the below entities in your manifest file android:hardwareAccelerated="false"
, android:largeHeap="true"
it will work for some environments.
<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 开发者的概念,尤其是这里:有效地显示位图
you should definitely read some of Androids Developer concept's, especially here:Displaying Bitmaps Efficiently
阅读所有 5 个主题并再次重写您的代码.如果它仍然不起作用,我们将很高兴看到您在教程材料中做错了什么.
Read all 5 topics and rewrite your code again. If it still doesn't work we will be happy to see what you've done wrong with the tutorial material.
这里是 SOF 中此类错误的一些可能答案
Here some of the possible answers for these type of errors in SOF
安卓:BitmapFactory.decodeStream() 内存不足,400KB 文件,2MB 空闲堆
如何解决Android中的java.lang.OutOfMemoryError故障
OutOfMemoryError 的解决方案: 位图大小超出虚拟机预算
来自@cjnash的评论
From the comments of @cjnash
对于添加此行后仍然崩溃的任何人,请尝试将图像粘贴到 res/drawable-xhdpi/文件夹而不是 res/drawable/中,这应该可以解决此问题
For anyone that still had crashes after they added this line, try sticking your image into your res/drawable-xhdpi/ folder instead of your res/drawable/ and this should resolve this issue
这篇关于Android:java.lang.OutOfMemoryError: 无法分配 23970828 字节的分配,2097152 个空闲字节和 2MB 直到 OOM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!