Null Canvas being passed into onDraw()?!

Problems with Canvas, OpenGL, etc...

Null Canvas being passed into onDraw()?!

Postby Zippy2013 » Sun Feb 03, 2013 5:54 am

Hi all

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!!

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.         import android.content.res.Resources;
  3.         import android.content.Context;
  4.         import android.graphics.Bitmap;
  5.         import android.graphics.BitmapFactory;
  6.         import android.graphics.Canvas;
  7.         import android.os.Handler;
  8.         import android.util.Log;
  9.         import android.view.MotionEvent;
  10.         import android.view.Surface;
  11.         import android.view.SurfaceHolder;
  12.         import android.view.SurfaceView;
  13.          
  14.         public class OptionsScreen extends SurfaceView implements
  15.           SurfaceHolder.Callback {       
  16.                
  17.                 //Create Variables
  18.                
  19.                 private SurfaceHolder thisHolder;
  20.                 private Context thisContext;
  21.                 private Handler thisHandler;
  22.                 private preThread thread;
  23.                 private Bitmap background;
  24.                 private Resources res;
  25.                 private Context myContext;
  26.                 private Handler myHandler;
  27.                
  28.                
  29.                 private Canvas c;
  30.                
  31.                
  32.                 public OptionsScreen(Context context) {
  33.                super(context);
  34.        
  35.                 myContext=context;                                                                      //This is the context passed into this constructor (this)
  36.                 thisHolder = getHolder();                                                             //Get surface holder
  37.                 thisHandler=getHandler();                                                             //Get Handler
  38.                 thisContext = getContext();                                                   //Get context
  39.                 res=getResources();                                                                   //Get resource
  40.                
  41.                 //add the callback surface holder
  42.                 getHolder().addCallback(this);
  43.                 //make focusable
  44.                 setFocusable(true);
  45.                 //create new thread
  46.                 thread = new preThread(thisHolder, thisContext, thisHandler);
  47.                 //create bitmaps from resources
  48.                 background = BitmapFactory.decodeResource(res, R.drawable.sky);
  49.         }
  50.          
  51.          @Override
  52.          public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  53.        
  54.                 Log.v("check","surfaceChanged run");
  55.          
  56.          }
  57.          
  58.          @Override
  59.          public void surfaceCreated(SurfaceHolder holder) {
  60.                                  
  61.                 Log.v("check","surfaceCreated run"+thread.getState());
  62.                  
  63.                 int height = this.getHeight();
  64.                 int width = this.getWidth();
  65.                
  66.                 if(thread.getState()==Thread.State.TERMINATED){                         //Has thread been stopped previously? could happen if the home key is pressed
  67.                         Log.v("check","Thread still exists!!!! - Starting a new one. "+thread.getState());  
  68.                         thread = new preThread(thisHolder, thisContext, thisHandler);
  69.                                        
  70.                 }
  71.                
  72.                 thread.setRunning(true);
  73.                 thread.start();
  74.          
  75.                 Log.v("check","Thread - "+thread.getState());
  76.                
  77.          }
  78.          
  79.          @Override
  80.          public void surfaceDestroyed(SurfaceHolder holder) {
  81.        
  82.                   Log.v("check","surfaceDestroyed run"+thread.getState());
  83.                  
  84.                   thread.setRunning(false);                                             //Set to false to exit run() method
  85.                  
  86.                  boolean retry = true;                                                  //Shut off rendering thread
  87.                           while (retry) {
  88.                             try {
  89.                                 thread.join();
  90.                                 retry = false;
  91.                               } catch (InterruptedException e) {
  92.                             // try again shutting down the thread
  93.                                        
  94.                            }
  95.                          
  96.                           }
  97.                        
  98.          }
  99.          
  100.          @Override
  101.          public boolean onTouchEvent(MotionEvent event) {
  102.                  Log.v("check","Surface Touched");
  103.                 Log.v("check","Thread - "+thread.getState());
  104.                  // System.exit(0);
  105.                        
  106.                 return super.onTouchEvent(event);
  107.          }
  108.          
  109.          @Override
  110.          protected void onDraw(Canvas canvas) {
  111.  
  112.                 // if (canvas!=null){
  113.                  
  114.                         canvas.drawBitmap(background, 0, 0, null);
  115.                         Log.v("Stop","Canvas is "+canvas);
  116.                  }
  117.          }
  118.        
  119.        
  120.          
  121.          
  122.          
  123.          
  124.          
  125.          
  126.          //*******************************************************************
  127.          //**                           run loop                                        **
  128.          //*******************************************************************
  129.          
  130.         protected class preThread extends Thread {
  131.                
  132.                 private SurfaceHolder mySurfaceHolder;
  133.                 private Context myContext;
  134.                
  135.                 public preThread(SurfaceHolder surfaceholder, Context context, Handler handler) {                               //Constructor
  136.                        
  137.                         mySurfaceHolder=surfaceholder;
  138.                         myContext=context;
  139.                         res = myContext.getResources();
  140.                        
  141.                        
  142.                 }
  143.                
  144.                
  145.                
  146.                          // flag
  147.                          private boolean running;
  148.                          public void setRunning(boolean running) {
  149.                           this.running = running;
  150.                          }
  151.                          
  152.                          @Override
  153.                          public void run() {
  154.                                  
  155.                                 while (running) {
  156.                            
  157.                                 try{c=mySurfaceHolder.lockCanvas();                                                                    
  158.                                
  159.                                 synchronized(mySurfaceHolder){
  160.                        
  161.                                
  162.                                         if (c==null){Log.v("check","Canvas is null for some reason");}
  163.                                        
  164.                                         Log.v("check","Drawing!!");
  165.                                                                                        
  166.                         onDraw(c);                                                                                                             
  167.        
  168.                         }
  169.                         }
  170.                         finally{
  171.                                 if (c != null){
  172.                
  173.                                 mySurfaceHolder.unlockCanvasAndPost(c);                                        
  174.                        
  175.                                 }
  176.                         }
  177.                                  
  178.                                  
  179.                                  
  180.                                  
  181.                                  
  182.                           }
  183.                          }
  184.                         }
  185.         }
  186.  
  187.  
  188.  
Parsed in 0.050 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
Zippy2013
Once Poster
Once Poster
 
Posts: 1
Joined: Sun Feb 03, 2013 5:39 am

Top

Return to Android 2D/3D Graphics - OpenGL Problems

Who is online

Users browsing this forum: No registered users and 2 guests