OutOfMemoryError sur timer
Bonjour à tous,
Je sollicite votre aide pour un problème de débordement mémoire.
Le programme doit mettre en route un chrono (timer) lorsque l'on appuis sur ok (après avoir rentrer les configurations de base) et doit s'arrêter dans une explosion formidable qu'elle est bien :-) si personne n'appuis à nouveau sur ok. Dans le cas contraire, le chrono doit s'arrêter, être remis à la valeur donnée pendant la configuration, et attendre qu'on déclenche à nouveau le timer.
Tout ce petit monde marche très bien, à un détails prêt (de taille quand même !) :
TRACE: <at java.lang.OutOfMemoryError>, Exception caught in Display class
java.lang.OutOfMemoryError (stack trace incomplete)
Ne sachant pas où se situe l'erreur (même si je penche pour des processus zombies, vous m'en direz plus...), je me suis dis que j'allais explicitement appeler le garbage collector. Ceci n'a rien changé...
Comme ce programme ne révolutionnera pas le monde, je le mets entier ici.
Je vous remercie par avance de toute l'aide que vous m'apporterez.
Cordialement, Alexaptor
PS : le deuxième timer pour la durée de la partie n'est pas encore intégré. En attendant vos réponses, je me penche sur ce problème.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
| // le code de la classe main
package bomb;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.media.*;
import java.util.Timer;
import java.io.*;
public class Main extends MIDlet implements CommandListener {
protected Command exitCommand, ok; // The exit command
protected Display display; // The display for this MIDlet
private Timer timer;
protected int initialCounter, counter, gameDuration;
private TextField delay, duration;
private Form form;
private boolean state;
public Main() {
this.counter = 0;
this.gameDuration = 0;
this.state = false; // test pour savoir si le timer est en route ou coupé
display = Display.getDisplay(this);
exitCommand = new Command("Exit", Command.EXIT, 0);
ok = new Command("OK", Command.OK, 2);
}
public void startApp() {
delay = new TextField("Delais explosion", "", 30, TextField.DECIMAL);
duration = new TextField("Durée partie", "", 30, TextField.DECIMAL);
form = new Form("Configurations");
form.append(delay);
form.append(duration);
form.addCommand(ok);
form.setCommandListener(this);
display.setCurrent(form); // formulaire des configurations de base
}
public void pauseApp() {}
public void destroyApp(boolean unconditional) {}
public void commandAction(Command c, Displayable s) {
String label = c.getLabel();
if (c == exitCommand) // fermeture programme
{
destroyApp(false);
notifyDestroyed();
}
else if(label.equals("OK")) // bouton ok enfoncé
{
if(this.counter == 0) // le délais n'est pas choisi, initialisation
{
this.counter = Integer.parseInt(this.delay.getString()) + 1;
this.initialCounter = this.counter; // on garde un compteur initial
this.gameDuration = Integer.parseInt(this.duration.getString());
}
else
{
if(!this.state) // state == true alors ou arrête et vis versa
this.startTimer();
else
this.stopExplosion();
}
}
}
public void armed()
{
this.stopTimer(); // on arrête le timer
form = new Form("Stand By");
form.addCommand(ok);
form.setCommandListener(this);
display.setCurrent(form); // on se remet à l'écoute
}
public void stopExplosion()
{
try
{
Player player = Manager.createPlayer(getClass().getResourceAsStream("disarmed.wav"), "audio/x-wav");
player.start(); // on joue le son "desarmé"
}
catch(MediaException e){}
catch(IOException e){}
this.armed(); // on prépare l'écoute
}
public void startTimer()
{
System.out.println("start counter : "+this.counter+" init : "+this.initialCounter);
this.state = true;
this.timer = new Timer();
// on lance un timer qui fera une action toutes les secondes
this.timer.scheduleAtFixedRate(new Explosion(this), 0, 1000);
}
public void stopTimer()
{
System.out.println("stop counter : "+this.counter+" init : "+this.initialCounter);
this.state = false;
this.counter = this.initialCounter;
this.timer.cancel();
System.gc(); // garbage collector
}
} |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| // le code du timerTask
package bomb;
import java.util.TimerTask;
import javax.microedition.lcdui.*;
import javax.microedition.media.*;
import java.io.*;
public class Explosion extends TimerTask {
private Main main;
public Explosion(Main main)
{
this.main = main;
}
public void run()
{
String text = "";
String ressource = "";
this.main.counter--;
if(this.main.counter == 0)
{
ressource = "explosionPCMSstereo.wav"; // son pour l'explosion
text = "BOOOM";
this.main.stopTimer();
this.cancel();
}
// compte à rebours
else if(this.main.counter == (this.main.initialCounter - 1))
{
ressource = "bombpl.wav";
text = String.valueOf(this.main.counter);
}
// pas de son à délais total - 2 secondes pour éviter la coupure du son précédent
else if(this.main.counter == (this.main.initialCounter - 2))
text = String.valueOf(this.main.counter);
else
{
if(this.main.counter > 5) // bip normal
ressource = "bip1.wav";
else
ressource = "bip2.wav"; // bip d'alerte
text = String.valueOf(this.main.counter);
}
if(this.main.counter != (this.main.initialCounter - 2))
{
try
{
Player player = Manager.createPlayer(getClass().getResourceAsStream(ressource), "audio/x-wav");
player.start(); // lecture du son
}
catch(MediaException e){}
catch(IOException e){}
}
Form form = new Form("Compte à rebours");
TextField delay = new TextField("Il reste", text, 30, TextField.UNEDITABLE);
form.append(delay);
form.addCommand(this.main.ok);
form.setCommandListener(this.main);
this.main.display.setCurrent(form); // affichage à l'écran du nombre de secondes
}
} |