[英]Android : java.lang.OutOfMemoryError:
我开发了一个在 Android 上使用大量图像的应用程序。
drawable 文件夹中有很多图像,比如超过 100 个,我正在开发图像动画应用程序。 我使用 imageview 来显示 GIF 图像。 我已经使用了将 gif 图像拆分为多个 PNG 格式图像的概念,然后使用它。
每次用户进入应用程序时,我都可以看到内存越来越大,直到用户收到java.lang.OutOfMemoryError
。
那么处理许多图像的最佳/正确方法是什么?
下面是我的代码:
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 文件夹)
<?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
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);
}
}
现在的问题是,当我尝试从一个活动移动到另一个具有相同的其他图像进行动画处理时,它给了我java.lang.OutOfMemory
错误。
我已经尝试过很多不同的解决方案,比如
@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();
}
}
等等,但任何解决方案都不适合我。 请帮我解决这个问题。 即使我提到了http://androidactivity.wordpress.com/2011/09/24/solution-for-outofmemoryerror-bitmap-size-exceeds-vm-budget/这个链接,但没有解决问题。
在您的 AndroidManifest.xml 中,将其保留在应用程序标签中,像这样添加 largeHeap:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"/>
尝试在 onPause() 停止动画。 因此,它很有可能没有获得 GCED。 还使用此站点http://tinypng.org优化您的位图,如果您不需要 alpha 层,请将其设置为 24bit
代替:
img.setBackgroundResource(R.drawable.dog_animation);
经过:
img.setImageBitmap(decodeSampleBitmapFromResource(R.drawable.dog_animation, width, height));
//dont forget to replace width and heigh by your imageview dimension
一个补充:
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;
}
和
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);
}
这是来自: http : //developer.android.com/training/displaying-bitmaps/load-bitmap.html
在上面的答案中缺少getResources()
img.setImageBitmap(decodeSampleBitmapFromResource(R.drawable.dog_animation, width, height));
所以它变成
img.setImageBitmap(decodeSampleBitmapFromResource(getResources(), R.drawable.dog_animation, width, height));
几天前,我遇到了同样的问题,并生成了类似的日志。 所以这就是我解决问题的方式。
我了解到在 Android Studio 的 ImageView 中加载的图像的像素不能超过宽度 1440 和高度 2560。
stackoverflow上投票最多的解决方案是在我们的清单文件中添加以下内容: android:hardwareAccelerated="false" , android:largeHeap="true"
正如这张图片中所示,当我实现这个时,错误没有被抛出,但这并不适用于所有设备,它只适用于我的模拟器。
因此,为了解决我的手机的这个困境,我在检查每个图像的像素后简单地将相关图像裁剪到限制像素,并丢弃太大而无法裁剪(调整大小)的图像。 注意:对于大量图像,您可以修改代码来检查超过所需像素数量的图像。
这是我在 github.com 上的问题的链接( allenbangai )
try {
//Code here that cause OutOfMemoryError
} catch (Error ee) {
ee.printStacktrace();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.