Recently had an issue in the BlackBerry Java application: it was reported to crash if the sounds were on and played often. However it didn’t crash if sounds were played once in a while. After some investigation it turned out that there are no memory leaks but some thing blocked the event dispatch queue. I asked for help on Stack Overflow and BlackBerry developer forums but that didn’t lead me anywhere except that I thought that something definitely gets locked. as my sounds were played via
SoundPlayer sp = new SoundPlayer((String) ((SoundNotification) arg).getArg() + Constants.EXTENSION_MIDI);
sp.setVolumeLevel(100);
sp.setMaxPlaybackMilis(4000);
invokeLater(sp);
i though that maybe this is the concurrent resource access issue as some of the melodies had to be played more than one time. So I implemented a simple manager like
class SoundManager implements Runnable {
boolean _isRunning;
Vector _playList;
public SoundManager() {
_isRunning = true;
_playList = new Vector(10);
}
public synchronized void stop() {
_isRunning = false;
}
public synchronized void addTrack(String item) {
_playList.insertElementAt(item, _playList.size());
notify();
}
public void run() {
while (_isRunning) {
if (_playList.isEmpty()) {
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
// do nothing
}
}
continue;
} else {
// no f..n queue in this SDK
String item = null;
synchronized (_playList) {
item = (String) _playList.elementAt(0);
_playList.removeElementAt(0);
}
final SoundPlayer sp = new SoundPlayer(item);
while (sp.isPlaying())
sleep(500);
sp.setVolumeLevel(100);
sp.setMaxPlaybackMilis(4000);
sp.run();
}
}
}
private void sleep(long timeout) {
try {
Thread.sleep(timeout);
} catch (InterruptedException e) {
}
}
}
and launched it along with application. BTW I was pretty much surprised that there IS NO QUEUE in 4.0.2 blackberry JDK SO i had to use Vector(well din’t really have to but it was used all around the code so I just grabbed it to be able to asap). This solved the issue.
However the the root of the problem was different from what I thought(though the solution is still correct). The root of the problem was my misunderstanding of the invokeLater method. It is misleading that it takes Runnable as a param – it actually executes your runnable on the event dispatch queue! Gotcha! Some of my sounds were 13 seconds long – no wonder firmware blocked the app with “Application is not responding” exception.