I have a problem with a drawing application. I have the error below when I leave the drawing activity (with the return button for example). I've looked at the posts but nothing seems to help me. Please, it would mean a lot if you could have a look at my drawingsurface activity, because I've been trying to make it work for a while! Thanks a lot :)
Error :
03-25 13:41:36.760: E/AndroidRuntime(6642): FATAL EXCEPTION: Thread-423
03-25 13:41:36.760: E/AndroidRuntime(6642): java.lang.IllegalArgumentException
03-25 13:41:36.760: E/AndroidRuntime(6642): at android.view.Surface.nativeUnlockCanvasAndPost(Native Method)
03-25 13:41:36.760: E/AndroidRuntime(6642): at android.view.Surface.unlockCanvasAndPost(Surface.java:457)
03-25 13:41:36.760: E/AndroidRuntime(6642): at android.view.SurfaceView$4.unlockCanvasAndPost(SurfaceView.java:812)
03-25 13:41:36.760: E/AndroidRuntime(6642): at com.ecp.drawing.DrawingSurface$DrawThread.run(DrawingSurface.java:80)
Main code of DrawingSurface :
public void run() {
Canvas canvas = null;
while (_run){
if(isDrawing == true){
try{
canvas = mSurfaceHolder.lockCanvas(null);
if(mBitmap == null){
mBitmap = Bitmap.createBitmap (1, 1, Bitmap.Config.ARGB_8888);
}
final Canvas c = new Canvas (mBitmap);
c.drawColor(0, PorterDuff.Mode.CLEAR);
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
commandManager.executeAll(c,previewDoneHandler);
previewPath.draw(c);
canvas.drawBitmap (mBitmap, 0, 0,null);
} finally {
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
There is already a surface destroyed function :
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
boolean retry = true;
thread.setRunning(false);
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
I would guess that lockCanvas
threw an exception, which left canvas
set to null. The exception sent execution to the finally
clause, which called unlockCanvasAndPost
, which threw a new exception. The new exception obscured the old.
(This looks a bit like a bug in 4.3, but this was posted before 4.3 came out.)
I had similar issues in 4.3 and after reading a while how other developers bypassed the bug I came to this.
Steps to keep in mind: lockCanvas, draw and then unlockCanvas.
/**
* Note: The drawing thread doesn't loop, it just runs once and exits
*/
@Override
public void run() {
/* This should never happen but just to be sure... */
if (mSurfaceHolder == null || mSurfaceView == null) {
return;
}
/**
* In order to work reliable on Nexus 7, we place ~500ms delay at the start of drawing thread
* (AOSP - Issue 58385)
*/
if (android.os.Build.BRAND.equalsIgnoreCase("google") &&
android.os.Build.MANUFACTURER.equalsIgnoreCase("asus") &&
android.os.Build.MODEL.equalsIgnoreCase("Nexus 7")) {
Log.w(this, "Sleep 500ms (Device: Asus Nexus 7)");
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {
}
}
Canvas canvas = null;
while (mRunning) {
try {
Surface surface = mSurfaceHolder.getSurface();
/* Check availability of surface */
if (surface != null && surface.isValid()) {
canvas = mSurfaceHolder.lockCanvas();
synchronized (mSurfaceHolder) {
if (canvas != null) {
//TODO call drawing code
}
}
}
} catch (Exception e) {
Log.e(TAG, "[Drawing Thread]", e);
} finally {
/**
* Do this in a finally so that if an exception is thrown during the above,
* we don't leave the Surface in an inconsistent state
*/
if (canvas != null && mSurfaceHolder != null) {
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
I hope this can help someone. ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With