Animation Drawable provoquant OutOfMemoryError sur la deuxième manche à Android
Je suis actuellement en train de développer un jeu et je suis en train d'utiliser un AnimationDrawable pour afficher une animation dans mon Menu Principal. Quand je lance le jeu une fois, il fonctionne parfaitement. Mais si je tape sur le bouton de retour, quand j'ouvre le jeu il me donne OutOfMemorryError.
Si j'ai frappé à la maison et de revenir au jeu, il charge mais ne montre pas l'animation, c'est vide là où il devrait être.
Je pense que lorsque l'on ouvre à nouveau le jeu, il essaie de charger l'animation, mais il est déjà chargé de l'exécution précédente, puis-je gratuit que la mémoire en quelque sorte? Comment puis-je traiter cette exception?
Recherche autour je peux trouver que c'est un problème commun dans Android, mais je ne pouvais pas trouver quelque chose d'utile.
Si c'est pertinent, mes images sont 310x316 et j'ai 114 images à charger, l'animation est chargé dans un xml.
Mon MainMenu classe:
public class MainMenuActivity extends Activity{
private String TAG = MainMenuActivity.class.getSimpleName();
ImageView rabbitMenu ;
AnimationDrawable ad;
public 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.mainmenu);
rabbitMenu = (ImageView) findViewById(R.id.rabbitMenu);
rabbitMenu.setImageResource(R.drawable.rabbit_menu_animation);
ad = (AnimationDrawable) rabbitMenu.getDrawable();
}
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
ad.start();
}
}
Le journal des erreurs:
01-31 16:13:11.320: E/AndroidRuntime(19550): FATAL EXCEPTION: main
01-31 16:13:11.320: E/AndroidRuntime(19550): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
01-31 16:13:11.320: E/AndroidRuntime(19550): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
01-31 16:13:11.320: E/AndroidRuntime(19550): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:563)
01-31 16:13:11.320: E/AndroidRuntime(19550): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:439)
Edit:
Après @OleGG suggestion et maintenant la deuxième manche va bien, mais sur la troisième manche, je suis apparemment en essayant d'utiliser un papier recyclé bitmap.
Donc j'ai donné de l'aide AnimationDrawable, et j'ai utilisé AsncTask à résoudre mon problème. Maintenant j'ai changer l'arrière-plan de l'ImageView sur mon onProgressUpdate(). Peut-être pas la meilleure approche, mais maintenant, je ne suis pas du tout avoir de problèmes! Voici mon AsyncTask code au cas où quelqu'un a le même problème!
private class DrawRabbit extends AsyncTask<Void, Integer, Void> {
private boolean running = true;
private int fps = 24;
private int frame = 10014;
private String drawableName;
@Override
protected Void doInBackground(Void... params) {
while (running){
try {
if (frame == 10014)
Thread.sleep(1000);
else
Thread.sleep(fps);
if (frame < 10160) {
frame++;
publishProgress(frame);
}
else
running = false;
} catch (InterruptedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
protected void onProgressUpdate(Integer... frame) {
drawableName = "rm" + frame[0];
int res_id = getResources().getIdentifier(drawableName, "drawable", getPackageName());
rabbitFrame.setBackgroundResource(res_id);
}
}
J'ai créé une classe pour l'affichage des animations de un drawable: stackoverflow.com/a/12519216/525319
Vous m'avez sauvé beaucoup de temps,merci
Malheureusement (comme je l'ai découvert après avoir essayé cette approche), AsynchTasks ne sont pas garantis à attendre pour la quantité de temps que vous spécifiez. Dans la pratique, cette approche a fini par me donner très agitée animations dont certaines sauté images. Il peut fonctionner dans certains cas, mais je serais prudent lorsque vous l'utilisez.
OriginalL'auteur caiocpricci2 | 2012-01-31
Vous devez vous connecter pour publier un commentaire.
Vous avez besoin pour libérer la mémoire utilisée par les bitmaps, lorsque vous quittez cet écran. Malheureusement, pour les versions antérieures d'Android (autant que je sache, ce n'était "fixe" depuis la version 3.0, mais j'ai peut-être mal) de mémoire pour les bitmaps est allouée par le biais de code natif et, ce qui est triste, la mémoire doit être libéré explicitement.
Donc, je suppose que vous essayer cette approche:
Ajoutez le code suivant pour la libération de la mémoire à onPause().
J'espère que ça va vous aider.
J'ai réussi à résoudre le problème en n'utilisant pas d'Animation Dessiné, j'ai fourni ma solution à la question. Depuis cela a résolu ce que j'ai demandé je l'accepte comme bonne réponse! Merci pour l'aide!
Vous pouvez obtenir "essayez d'utiliser un papier recyclé bitmap" dans deux cas: 1) Si vous ne le manipulez pas la création|suppression de bitmap correctement (par exemple en essayant de réutiliser drawable, tandis que le sous-jacent Bitmap est déjà recyclé). 2) Sur certains appareils (LG Optimus, par exemple) sous-jacent du code natif pour le format bitmap de chargement, ce que je comprends, en utilisant une sorte de "mise en cache". Cela signifie que si Drawable a été chargé précédemment, le système pense, qu'il est encore dans la mémoire et n'a pas besoin d'être rechargé, même si j'ai recyclé le bitmap.
je vous remercie. j'ai besoin de cette.
merci , ça a fonctionné pour moi.Je l'ai utilisé sur les détruire et cela a fonctionné pour moi
OriginalL'auteur OleGG
Donc, j'ai réussi à résoudre mon problème avec cette approche:
Créé un AsyncTask pour le dessin
et commencer à onWindowsFocusChanged
Espère que cela aide quelqu'un!
Si vous avez un sleep() dans votre thread de l'interface utilisateur, vous le faites mal.
Non, je ne suis pas, je dors dans
doInBackground()
!OriginalL'auteur caiocpricci2
Vous pouvez essayer en réduisant la taille des images. Mon cas, cela a fonctionné.
OriginalL'auteur sujith
juste ajouter "android:largeHeap="true"" dans la balise application android manifeste! 🙂
OriginalL'auteur matin ashtiani
ajouter ces deux lignes dans votre fichier manifeste android android:hardwareAccelerated="true" et android:largeHeap="true"
Espère que cela va vous aider.
OriginalL'auteur Hitesh Dhamshaniya