I'm rather new to Java and I'm having some trouble with threading.
I have read the essential concurrency java docs multiple times and lots of other java threading documentation but I'm still lost.
I'm writing a JavaME MIDP 2 program which has animated GIF images.
Each image has it's own animation thread.
Basically the problem is sometimes the program just freezes up.
I'm quite certain it's a threading issue.
public class GifAnimation
{
GifAnimation()
{
myAnimator = null;
myThread = null;
myActive = false;
myPaused = false;
}
void Start(String imageFile, Canvas theCanvas)
{
Stop();
myAnimator = new GifAnimator();
myAnimator.setup(imageFile, this, theCanvas);
myActive = true;
myThread = new Thread(myAnimator);
myThread.start();
}
void Stop()
{
myAnimator = null;
myActive = false;
myPaused = false;
if (null != myThread && myThread.isAlive())
{
try
{
myThread.interrupt();
myThread.join();
}
catch (InterruptedException e)
{
}
}
myThread = null;
}
public void Pause()
{
if (myPaused)
return;
myPaused = true;
myThread.interrupt();
}
public void Resume()
{
if (!myPaused)
return;
myPaused = false;
myThread.notify();
}
public synchronized Image getImage()
{
return myImage;
}
public synchronized void setImage(Image i)
{
myImage = i;
}
private GifAnimator myAnimator;
private Thread myThread;
boolean isActive;
boolean isPaused;
private Image myImage;
}
public class GifAnimator implements Runnable
{
private GifDecoder myGifDecoder;
private GifAnimation myAnimation;
private Canvas myCanvas;
public void setup(String imageFile, GifAnimation theAnimation, Canvas theCanvas)
{
myAnimation = theAnimation;
myCanvas = theCanvas;
myGifDecoder = new GifDecoder();
myGifDecoder.read(imageFile);
myAnimation.setImage(myGifDecoder.getImage());
}
public void run()
{
int n = myGifDecoder.getFrameCount();
int t = 0;
while (myAnimation.isActive())
{
for (int i = 0; i < n; ++i)
{
while (myAnimation.isPaused())
{
synchronized (this)
{
try
{
wait();
}
catch (InterruptedException e)
{
}
}
}
myAnimation.setImage(myGifDecoder.getFrame(i));
t = myGifDecoder.getDelay(i);
myCanvas.repaint();
myCanvas.serviceRepaints();
try
{
Thread.sleep(t);
}
catch (InterruptedException e)
{
}
}
}
}
}
My main thread is a Canvas derived class.
It has a GifAnimation member variable.
It calls GifAnimation.Next() when a certain key is pressed.
Here's the relevant bits:
public class Main extends Canvas
{
private GifAnimation myAnimation;
public Main()
{
super();
Next();
}
protected void showNotify()
{
myAnimation.Resume();
}
protected void hideNotify()
{
myAnimation.Pause();
}
protected void paint(Graphics g)
{
Image img = myAnimation.getImage();
if (null != img)
g.drawImage(img, 0, 0, Graphics.TOP | Graphics.LEFT);
}
private void Next()
{
...
myAnimation.Start(someNewImage, this);
repaint();
}
public void keyPressed(int keyCode)
{
switch (keyCode)
{
case Canvas.KEY_STAR:
Next();
break;
}
}
}
I apologize for the lengthiness of it all, I've stripped it down as much as possible.
Could someone please help me synchronize things here?
I suspect I'm using wait()/notify() incorrectly but I'm not sure (though I have read about it as much as possible).
I think "Deadlock Drawing" (sonyericsson developer website) may be part (or all!) of the problem but I really don't know.
I could really use some help on this, I'm utterly lost.
This program is important to me, it's a learning aid I intend to use every day.