title: Unexpected NullPointerException in SurfaceView-Thread on API-level 15
body: <p>I have programmed an App which I wanted to test on higher API-Levels for checking the compatibility. For API 10 (2.3.3) there were no problems, but as soon as I ran my app on API 15 (4.0.3) I got an NullPointerException in one of my SurfaceViews when I was quitting the Activity.
  I have to say that i solved the problem, but i can't figure out why the Exception occured actually. So maybe you could tell me.</p>
  
  <p>Here is the code that worked for me on API 10:
  It's the common structure of the <code>run()</code>-method.</p>
  
  <pre><code>public void run() {
      while (mThreadActive) {
          c = null;
          try {
              c = mSurfaceHolder.lockCanvas(null);
              synchronized (mSurfaceHolder) {
                  if(mState == 1) {
                      updateValues();
                      updateAnimation();
                  }
                  doDraw(c);
              }
          } finally {
              if (c != null) {
                  mSurfaceHolder.unlockCanvasAndPost(c);
              }
          }
      }
  }
  </code></pre>
  
  <p>On API 15 when quitting the activity:
  The Exception accoured when the <code>doDraw()</code>-method tried to write on "c". I checked c and found out it was null, so no surprise I got an Exception. I also checked <code>mThreadActive</code> and found out that although i set it to false, the <code>while</code>-loop still triggers.
  Here is the Code sample:</p>
  
  <pre><code>public void run() {
      while (mThreadActive) {
          c = null;
          try {
              c = mSurfaceHolder.lockCanvas(null);
              synchronized (mSurfaceHolder) {
                  if(mState == 1) {
                      updateValues();
                      updateAnimation();
                  }
  
                  if(!mThreadActive)    // so it really is!
                      Log.d("Thread", "mThreadActive is false!");
  
                  if(c == null)   // so it is too!
                      Log.d("Thread", "c is null!");
  
                  doDraw(c);   // error
              }
          } finally {
              if (c != null) {
                  mSurfaceHolder.unlockCanvasAndPost(c);
              }
          }
      }
  }
  </code></pre>
  
  <p>I can imagine why <code>mThreadActive</code> becomes false AFTER being checked by the <code>while</code>-statement, but I can't figure out why "c" is null after <code>mSurfaceHolder.lockCanvas(null)</code>. It seems that the code is not running sequential.</p>
  
  <p>Well, the solution would be checking <code>c != null</code> before drawing on it:</p>
  
  <pre><code>public void run() {
      while (mThreadActive) {
          c = null;
          try {
              c = mSurfaceHolder.lockCanvas(null);
              synchronized (mSurfaceHolder) {
                  if(mState == 1) {
                      updateValues();
                      updateAnimation();
                  }
                  if(c != null) // prevent drawing on c if c doesnt exist.
                      doDraw(c);
              }
          } finally {
              if (c != null) {
                  mSurfaceHolder.unlockCanvasAndPost(c);
              }
          }
      }
  }
  </code></pre>
  
  <p>So why do i get an Exception on API 15 whereas it works fine on API 10?
  Another funny thing is, that i have other SurfaceViews with the same structure, but in comparison to this one, they work all fine!
  Why is the code not running sequential? Is it because I am testing on an emulator (which is pretty laggy)?</p>
  
  <p>Thank You.</p>