Note that there are some explanatory texts on larger screens.

plurals
  1. POnull Canvas in SurfaceView Thread, despite stopping Thread in surfaceDestroyed() - only on Android 4 / ICS
    primarykey
    data
    text
    <p>I have a SurfaceView extension where the bare bones of it are implemented as in the <a href="http://developer.android.com/resources/samples/LunarLander/index.html" rel="noreferrer">Lunar Lander</a> example. That is, the <code>run()</code> method of the drawing <code>Thread</code> is essentially:</p> <pre><code>public void run() { while (mRun) { Canvas c; try { c = mSurfaceHolder.lockCanvas(); synchronized (mSurfaceHolder) { doDraw(c); // Main drawing method - not included in this code snippet } } 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 (c != null) { mSurfaceHolder.unlockCanvasAndPost(c); } } } } } </code></pre> <p>And the <code>Thread</code> is properly stopped when the surface is destroyed:</p> <pre><code>public void surfaceDestroyed(SurfaceHolder holder) { // we have to tell thread to shut down &amp; wait for it to finish, or else // it might touch the Surface after we return and explode boolean retry = true; thread.setRunning(false); while (retry) { try { thread.join(); retry = false; } catch (InterruptedException e) { } } } </code></pre> <p>On devices I have usually tested on to date (HTC Desire, Desire HD, and Archos 101 which between them have OS 2.2 and 2.3.3 if I remember right) there has never been a problem with the above. That is, when the surface is destroyed because the user backs out of the <code>Activity</code> or another <code>Activity</code> is invoked on top, the code within <code>surfaceDestroyed()</code> always ensures that <code>mSurfaceHolder.lockCanvas()</code> would never be called for it to return <code>null</code>. </p> <p>The difference I've found on my new HTC One X which is running Android 4 / ICS, however, is that during the call to method <code>surfaceDestroyed()</code> (i.e. code within that method is still executing) my drawing <code>Thread</code> would be given a <code>null</code> canvas from <code>mSurfaceHolder.lockCanvas()</code>. This would of course cause an application crash. On my One X, this will happen <em>every</em> single time the surface is destroyed - whether it be due to rotating the phone, backing out of the <code>Activity</code>, etc. </p> <p>I'm confused about this because I was under the impression that <code>mSurfaceHolder.lockCanvas()</code> should return a non-<code>null</code> <code>Canvas</code> until <code>surfaceDestroyed()</code> has actually <em>exited</em>. Indeed, this is what the Javadoc says:</p> <p><code>This is called immediately before a surface is being destroyed. After returning from this call, you should no longer try to access this surface. If you have a rendering thread that directly accesses the surface, you must ensure that thread is no longer touching the Surface before returning from this function.</code></p> <p>My solution for now is to just check for <code>null</code>. This works fine:</p> <pre><code>if(c != null){ doDraw(c); // Main drawing method - not included in this code snippet } </code></pre> <p>But, any ideas why I'm suddenly having to do this for Android 4 / ICS?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload