Really hoping someone can point me in the right direction here.
When I run my code, and then press either the back or home key, a null canvas (for some reason) is being passed into onDraw() and the app force closes.
The code was initially much larger and complex but after months of being unable to find out why it was happening, I stripped it all out and started from scratch with a much simplified version as follows but still get exactly the same problem!!
Using java Syntax Highlighting
- import android.content.res.Resources;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.os.Handler;
- import android.util.Log;
- import android.view.MotionEvent;
- import android.view.Surface;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
- public class OptionsScreen extends SurfaceView implements
- SurfaceHolder.Callback {
- //Create Variables
- private SurfaceHolder thisHolder;
- private Context thisContext;
- private Handler thisHandler;
- private preThread thread;
- private Bitmap background;
- private Resources res;
- private Context myContext;
- private Handler myHandler;
- private Canvas c;
- public OptionsScreen(Context context) {
- super(context);
- myContext=context; //This is the context passed into this constructor (this)
- thisHolder = getHolder(); //Get surface holder
- thisHandler=getHandler(); //Get Handler
- thisContext = getContext(); //Get context
- res=getResources(); //Get resource
- //add the callback surface holder
- getHolder().addCallback(this);
- //make focusable
- setFocusable(true);
- //create new thread
- thread = new preThread(thisHolder, thisContext, thisHandler);
- //create bitmaps from resources
- background = BitmapFactory.decodeResource(res, R.drawable.sky);
- }
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- Log.v("check","surfaceChanged run");
- }
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- Log.v("check","surfaceCreated run"+thread.getState());
- int height = this.getHeight();
- int width = this.getWidth();
- if(thread.getState()==Thread.State.TERMINATED){ //Has thread been stopped previously? could happen if the home key is pressed
- Log.v("check","Thread still exists!!!! - Starting a new one. "+thread.getState());
- thread = new preThread(thisHolder, thisContext, thisHandler);
- }
- thread.setRunning(true);
- thread.start();
- Log.v("check","Thread - "+thread.getState());
- }
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- Log.v("check","surfaceDestroyed run"+thread.getState());
- thread.setRunning(false); //Set to false to exit run() method
- boolean retry = true; //Shut off rendering thread
- while (retry) {
- try {
- thread.join();
- retry = false;
- } catch (InterruptedException e) {
- // try again shutting down the thread
- }
- }
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- Log.v("check","Surface Touched");
- Log.v("check","Thread - "+thread.getState());
- // System.exit(0);
- return super.onTouchEvent(event);
- }
- @Override
- protected void onDraw(Canvas canvas) {
- // if (canvas!=null){
- canvas.drawBitmap(background, 0, 0, null);
- Log.v("Stop","Canvas is "+canvas);
- }
- }
- //*******************************************************************
- //** run loop **
- //*******************************************************************
- protected class preThread extends Thread {
- private SurfaceHolder mySurfaceHolder;
- private Context myContext;
- public preThread(SurfaceHolder surfaceholder, Context context, Handler handler) { //Constructor
- mySurfaceHolder=surfaceholder;
- myContext=context;
- res = myContext.getResources();
- }
- // flag
- private boolean running;
- public void setRunning(boolean running) {
- this.running = running;
- }
- @Override
- public void run() {
- while (running) {
- try{c=mySurfaceHolder.lockCanvas();
- synchronized(mySurfaceHolder){
- if (c==null){Log.v("check","Canvas is null for some reason");}
- Log.v("check","Drawing!!");
- onDraw(c);
- }
- }
- finally{
- if (c != null){
- mySurfaceHolder.unlockCanvasAndPost(c);
- }
- }
- }
- }
- }
- }
Parsed in 0.049 seconds, using GeSHi 1.0.8.4
The only workaround I've found is to put check the cavas that's been passed into onDraw() against null and if it is, to skip the whole onDraw() method - this works fine, but obviously isn't the right way of doing things, would be grateful for any pointers!
Thanks

