I am trying to make a game for android. It is based on a 2d map, which the user can move around the screen. On the screen are several buttons, for example ‘Shop’. When I user presses the button, I would like to fill the screen with a shop interface.
So far my approach has been as follows:
I have a mapView, and a map thread
-
public class MapView extends SurfaceView implements SurfaceHolder.Callback {} -
public class MapThread extends Thread { ... }
The map thread periodically calls the onDraw method in MapView, which draws the map to the screen, whilst event listeners in MapView deal with moving the map.
For the shop, I have a similar setup, with a ShopThread and a ShopView. When the shop button is pressed, my idea is to stop the MapThread, and start the ShopThread. This would mean only the ‘onDraw’ method of ShopView will be called, allowing me to draw the shop interface.
In reponse to the button press I have the following code:
(I pass the activity between each of the views via the variable topPage)
mapThread.isRunning = false; //stop the map thread
setVisibility(INVISIBLE);
// add showView to the activity and start the ShopThread
topPage.addContentView(shopView,new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT) );
shopView.startThread();
My problem is that the game freezes for a while when trying to access the shop. The screen just remains black and doesn’t respond for around 30 seconds to a minute. I will also get the ‘force close’ or ‘wait’ error message from the OS. If I press wait, the ShopView will occasionally start working completely correctly.
I have narrowed it down to the run method in my ShopThread class.
public void run() {
Canvas c;
while (isRunning){
c = null;
try {
c = ShopView.getHolder().lockCanvas(null);
synchronized (ShopView.getHolder()) {
if(c != null)
ShopView.onDraw(c);
}
} finally {
if( c != null){
ShopView.getHolder().unlockCanvasAndPost(c);
}
}
}
}
The line c = ShopView.getHolder().lockCanvas(null); is simply returning null. I have placed Log.v statements in the other updateThreads and they appear to have all stopped. What is keeping a lock on the canvas, is there something I am missing?
I found the problem. I managed to fix it, but I am unsure why is was a problem in the first place.
I originally created a
ShopViewobject in myMapViewclass and started theShopThreadmanually when I wanted to start drawing the shop to the canvas. Instead of this, I changed it so that the ShopView thread was created and started in thesurfaceCreated()function