Androidでたくさんの画像を使うアプリを開発しました。
ドローアブルフォルダには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で、これをapplicationタグ内に保持し、次のようにlargeHeapを追加します。
<application
Android:allowBackup="true"
Android:icon="@mipmap/ic_launcher"
Android:label="@string/app_name"
Android:largeHeap="true"/>
onPause()でアニメーションを停止してみてください。そのため、GCEDを取得できない可能性が高くなります。このサイトを使用してurビットマップも最適化します http://tinypng.org 、アルファレイヤーが不要な場合は、24ビットに設定します
上記の回答にはgetResources()
がありません
img.setImageBitmap(decodeSampleBitmapFromResource(R.drawable.dog_animation, width, height));
そうなる
img.setImageBitmap(decodeSampleBitmapFromResource(getResources(), R.drawable.dog_animation, width, height));
交換:
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