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.
Here is the code that worked for me on API 10:
It's the common structure of the run()
-method.
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);
}
}
}
}
On API 15 when quitting the activity:
The Exception accoured when the doDraw()
-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 mThreadActive
and found out that although i set it to false, the while
-loop still triggers.
Here is the Code sample:
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);
}
}
}
}
I can imagine why mThreadActive
becomes false AFTER being checked by the while
-statement, but I can't figure out why "c" is null after mSurfaceHolder.lockCanvas(null)
. It seems that the code is not running sequential.
Well, the solution would be checking c != null
before drawing on it:
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);
}
}
}
}
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)?
Thank You.