安卓:java.lang.OutOfMemoryError:
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19558713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android : java.lang.OutOfMemoryError:
提问by InnocentKiller
I developed an application that uses lots of images on Android.
我开发了一个在 Android 上使用大量图像的应用程序。
There are lots of images present in drawable folder say more then 100, I am developing application for animation of images. I used imageview to show GIF images. I have used the concept of Split gif images into multiple PNG format images and then use it.
drawable 文件夹中有很多图像,比如超过 100 个,我正在开发图像动画应用程序。我使用 imageview 来显示 GIF 图像。我已经使用了将 gif 图像拆分为多个 PNG 格式图像的概念,然后使用它。
Each time the user enters to the app, I can see the memory growing more and more until user gets the java.lang.OutOfMemoryError
.
每次用户进入应用程序时,我都可以看到内存越来越大,直到用户获得java.lang.OutOfMemoryError
.
So what is the best/correct way to handle many images?
那么处理许多图像的最佳/正确方法是什么?
Below is my code:
下面是我的代码:
dog_animation.xml
dog_animation.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/DogView"
android:orientation="vertical" >
<ImageView
android:id="@+id/dog_animation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.19" />
dog_animation.xml (Drawable folder)
dog_animation.xml(Drawable 文件夹)
<?xml version="1.0" encoding="utf-8"?>
<item
android:drawable="@drawable/image"
android:duration="50"/>
<item
android:drawable="@drawable/image1"
android:duration="50"/>
<item
android:drawable="@drawable/image2"
android:duration="50"/>
<item
android:drawable="@drawable/image3"
android:duration="50"/>
<item
android:drawable="@drawable/image4"
android:duration="50"/>
<item
android:drawable="@drawable/image5"
android:duration="50"/>
<item
android:drawable="@drawable/image6"
android:duration="50"/>
<item
android:drawable="@drawable/image7"
android:duration="50"/>
<item
android:drawable="@drawable/image8"
android:duration="50"/>
<item
android:drawable="@drawable/image9"
android:duration="50"/>
<item
android:drawable="@drawable/image10"
android:duration="50"/>
<item
android:drawable="@drawable/image11"
android:duration="50"/>
<item
android:drawable="@drawable/image12"
android:duration="50"/>
<item
android:drawable="@drawable/image13"
android:duration="50"/>
<item
android:drawable="@drawable/image14"
android:duration="50"/>
<item
android:drawable="@drawable/image15"
android:duration="50"/>
<item
android:drawable="@drawable/image16"
android:duration="50"/>
<item
android:drawable="@drawable/image17"
android:duration="50"/>
<item
android:drawable="@drawable/image18"
android:duration="50"/>
<item
android:drawable="@drawable/image19"
android:duration="50"/>
<item
android:drawable="@drawable/image20"
android:duration="50"/>
<item
android:drawable="@drawable/image21"
android:duration="50"/>
<item
android:drawable="@drawable/image22"
android:duration="50"/>
<item
android:drawable="@drawable/image23"
android:duration="50"/>
<item
android:drawable="@drawable/image24"
android:duration="50"/>
<item
android:drawable="@drawable/image25"
android:duration="50"/>
<item
android:drawable="@drawable/image26"
android:duration="50"/>
<item
android:drawable="@drawable/image27"
android:duration="50"/>
<item
android:drawable="@drawable/image28"
android:duration="50"/>
<item
android:drawable="@drawable/image29"
android:duration="50"/>
<item
android:drawable="@drawable/image30"
android:duration="50"/>
<item
android:drawable="@drawable/image31"
android:duration="50"/>
<item
android:drawable="@drawable/image32"
android:duration="50"/>
<item
android:drawable="@drawable/image33"
android:duration="50"/>
<item
android:drawable="@drawable/image34"
android:duration="50"/>
<item
android:drawable="@drawable/image35"
android:duration="50"/>
<item
android:drawable="@drawable/image36"
android:duration="50"/>
<item
android:drawable="@drawable/image37"
android:duration="50"/>
<item
android:drawable="@drawable/image38"
android:duration="50"/>
<item
android:drawable="@drawable/image39"
android:duration="50"/>
<item
android:drawable="@drawable/image40"
android:duration="50"/>
<item
android:drawable="@drawable/image41"
android:duration="50"/>
<item
android:drawable="@drawable/image42"
android:duration="50"/>
<item
android:drawable="@drawable/image43"
android:duration="50"/>
<item
android:drawable="@drawable/image44"
android:duration="50"/>
<item
android:drawable="@drawable/image45"
android:duration="50"/>
<item
android:drawable="@drawable/image46"
android:duration="50"/>
<item
android:drawable="@drawable/image47"
android:duration="50"/>
<item
android:drawable="@drawable/image48"
android:duration="50"/>
<item
android:drawable="@drawable/image49"
android:duration="50"/>
<item
android:drawable="@drawable/image50"
android:duration="50"/>
<item
android:drawable="@drawable/image51"
android:duration="50"/>
<item
android:drawable="@drawable/image52"
android:duration="50"/>
<item
android:drawable="@drawable/image53"
android:duration="50"/>
<item
android:drawable="@drawable/image54"
android:duration="50"/>
<item
android:drawable="@drawable/image55"
android:duration="50"/>
<item
android:drawable="@drawable/image56"
android:duration="50"/>
Dog_Animation.java
Dog_Animation.java
public class Dog_Animation extends Activity {
Timer timer = new Timer();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.dog_animation);
ImageView img = (ImageView) findViewById(R.id.dog_animation);
img.setBackgroundResource(R.drawable.dog_animation);
AnimationDrawable frameAnimation = (AnimationDrawable) img
.getBackground();
frameAnimation.start();
timer.schedule(new TimerTask() {
public void run() {
Intent intent = new Intent(Dog_Animation.this,
Man_Animation.class);
startActivity(intent);
}
}, 10000);
}
}
Now the problem is when i try to move from one activity to another which has same some other image to animate it's giving me error of java.lang.OutOfMemory
.
现在的问题是,当我尝试从一个活动移动到另一个具有相同的其他图像进行动画处理时,它给了我java.lang.OutOfMemory
.
I have tried with so many different solution like
我已经尝试过很多不同的解决方案,比如
@Override
protected void onDestroy() {
super.onDestroy();
unbindDrawables(findViewById(R.id.DogView));
System.gc();
}
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
and so other also but any solution is not working for me. Please help me to solve this issue. even i have referred http://androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/this link but not getting solve the issue.
等等,但任何解决方案都不适合我。请帮我解决这个问题。即使我提到了http://androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/这个链接,但没有解决问题。
回答by Pumpkin
Replace:
代替:
img.setBackgroundResource(R.drawable.dog_animation);
By:
经过:
img.setImageBitmap(decodeSampleBitmapFromResource(R.drawable.dog_animation, width, height));
//dont forget to replace width and heigh by your imageview dimension
An add:
一个补充:
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
and
和
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
This is from: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
这是来自:http: //developer.android.com/training/displaying-bitmaps/load-bitmap.html
回答by hepizoj
try stopping your animation at onPause(). there is a big chance its not getting GCED because of that. also optimize ur bitmaps using this site http://tinypng.org, if you don't need the alpha layer, set it to 24bit
尝试在 onPause() 停止动画。因此,它很有可能没有获得 GCED。还使用此站点http://tinypng.org优化您的位图,如果您不需要 alpha 层,请将其设置为 24bit
回答by Petar Karan
In the above answer there is a getResources()
missing in
在上面的答案中有一个getResources()
缺失
img.setImageBitmap(decodeSampleBitmapFromResource(R.drawable.dog_animation, width, height));
so it becomes
所以它变成
img.setImageBitmap(decodeSampleBitmapFromResource(getResources(), R.drawable.dog_animation, width, height));
回答by Arfan Mirza
try {
//Code here that cause OutOfMemoryError
} catch (Error ee) {
ee.printStacktrace();
}
回答by Ismaran Duwadi
In your AndroidManifest.xml keep this inside application tag, add largeHeap like this:
在您的 AndroidManifest.xml 中,将其保留在应用程序标签中,像这样添加 largeHeap:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"/>
回答by Kamadje Allen
Few days ago, I had the same issue and it generated a similar log. So this is how I went about solving the issue.
几天前,我遇到了同样的问题,并生成了类似的日志。所以这就是我解决问题的方式。
I learned that the pixel of an image being loaded in an ImageView in Android Studio mustn't exceed width 1440 and height 2560.
我了解到在 Android Studio 的 ImageView 中加载的图像的像素不能超过宽度 1440 和高度 2560。
The most voted solution on stackoverflowasked is to add the following in our manifest file: android:hardwareAccelerated="false" , android:largeHeap="true"
在stackoverflow上投票最多的解决方案是在我们的清单文件中添加以下内容: android:hardwareAccelerated="false" , android:largeHeap="true"
just as show in this imageAs I implemented this, the error wasn't thrown, but this did not work for all devices, it rather only worked for my emulator.
正如这张图片所示,当我实现这个时,没有抛出错误,但这并不适用于所有设备,它只适用于我的模拟器。
So, to solve this dilema for my phone, I simply cropped the associated images to the limit pixel after checking the pixel of each image and discarded that was too large for cropping(resizing). Note: for a large number of images you can right a code that checks for the images that exceed the amount of pixel required.
因此,为了解决我的手机的这个困境,我在检查每个图像的像素后简单地将相关图像裁剪到限制像素,并丢弃太大而无法裁剪(调整大小)的图像。注意:对于大量图像,您可以修改代码来检查超过所需像素数量的图像。
this is the link to my issue on github.com (allenbangai)
这是我在 github.com 上的问题的链接(allenbangai)