Exception locking surface - lockCanvas() returns a null?

by mcmc » Sat, 04 Apr 2009 01:32:35 GMT


Sponsored Links
 Everytime it hits the "c = mHolder.lockCanvas();" line, it pops up
with that same error mentioned below.

Also, I realize that c returns a null after called lockCanvas(), but
mHolder is still active. Why might this be?


I'm getting the following error as seen from the logcat window:

E/SurfaceComposerClient(  608): eLocked set when entering lock_layer
(), layer=1 (lcblk=0x410480a0), state=00000022
E/SurfaceHolder(  608): Exception locking surface
E/SurfaceHolder(  608): java.lang.IllegalArgumentException
E/SurfaceHolder(  608):         at
android.view.Surface.lockCanvasNative(Native Method)
E/SurfaceHolder(  608):         at android.view.Surface.lockCanvas
(Surface.java:190)
E/SurfaceHolder(  608):         at android.view.SurfaceView
$2.internalLockCanvas(SurfaceView.java:549)
E/SurfaceHolder(  608):         at android.view.SurfaceView
$2.lockCanvas(SurfaceView.java:528)


This is the basis of my code, which is primarily based on the
lunarview:

@Override
public void run() {
    while (mRun) {
        Canvas c = null;
        try {
            mHolder = getHolder();      //make sure holder is updated
            c = mHolder.lockCanvas();
            synchronized (mHolder) {
                if (mMode == STATE_RUNNING && c != null){
                    doDraw(c);
                }
            }
        } 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) {
                mHolder.unlockCanvasAndPost(c);
            }
        }
    }
}


Can someone get back to me ASAP, this is urgent.

Thanks a lot,
mcmc

--~--~---------~--~----~------------~-------~--~----~



Exception locking surface - lockCanvas() returns a null?

by Streets Of Boston » Sat, 04 Apr 2009 01:38:48 GMT


 I don't have a direct answer for you.
But this is what i usually do when problems baffle me. I browse the
git-source of Android.

Try to find the source of SurfaceHolder and find the lockCanvas( ) and
see why it may throw an exception.



--~--~---------~--~----~------------~-------~--~----~


Sponsored Links


Exception locking surface - lockCanvas() returns a null?

by ellipsoidmob...@googlemail.com » Mon, 06 Apr 2009 02:15:57 GMT


 Might also be worth checking that you aren't drawing into the surface
from a different thread, and that you aren't drawing before the
surfaceCreated() callback
--~--~---------~--~----~------------~-------~--~----~



Exception locking surface - lockCanvas() returns a null?

by mcmc » Tue, 07 Apr 2009 02:48:24 GMT


 actually, I am drawing onto the surface from a different thread...
that's not allowed?? how would I go around doing this?

I'm not drawing before the surfaceCreated() callback...

On Apr 5, 11:15am, "ellipsoidmob...@googlemail.com"


--~--~---------~--~----~------------~-------~--~----~



Exception locking surface - lockCanvas() returns a null?

by mcmc » Tue, 07 Apr 2009 08:38:14 GMT


 i, now, combined the two threads into one, and I still get the same
error at lockCanvas().

any ideas would be much appreciated. thank you.




--~--~---------~--~----~------------~-------~--~----~



Exception locking surface - lockCanvas() returns a null?

by ellipsoidmob...@googlemail.com » Tue, 07 Apr 2009 20:34:42 GMT


 Oh - I think I can see the problem in your code now. You've got your
'finally' block outside of your while loop, rather than inside it.
This means that you are calling lockCanvas() repeatedly without
calling UnlockCanvasAndPost(). The exception is going to be thrown on
the 2nd iteration of the while loop, as you are calling lockCanvas()
when the canvas is already locked.

--~--~---------~--~----~------------~-------~--~----~



Exception locking surface - lockCanvas() returns a null?

by mcmc » Wed, 08 Apr 2009 03:25:34 GMT


 my finally is inside my while loop.
but maybe i'm not doing it correctly...
do I have to call unlockCanvasAndPost every time I call lockCanvas
(even if it returns a null)? or do I only call unlockCanvasAndPost if
the lockCanvas returns a non null canvas (which is my current
implementation)?

On Apr 7, 5:34am, "ellipsoidmob...@googlemail.com"


--~--~---------~--~----~------------~-------~--~----~



Exception locking surface - lockCanvas() returns a null?

by mcmc » Wed, 08 Apr 2009 03:28:39 GMT


 my finally is inside my while loop.
but maybe i'm not doing it correctly...
do I have to call unlockCanvasAndPost every time I call lockCanvas
(even if it returns a null)? or do I only call unlockCanvasAndPost if
the lockCanvas returns a non null canvas (which is my current
implementation)?

On Apr 7, 5:34am, "ellipsoidmob...@googlemail.com"


--~--~---------~--~----~------------~-------~--~----~



Exception locking surface - lockCanvas() returns a null?

by ellipsoidmob...@googlemail.com » Wed, 08 Apr 2009 19:04:46 GMT


 Sorry, I misread your code before. It looks the same as lunarview and
also the same as my game loop, both of which work fine, so I think it
must be something you are doing outside of this code snippet.

You do have to unlock for every successful lock (but not if you get a
null back), so your code looks correct to me in this regard

The error looks like the one you would get if the canvas was already
locked when you called lock, so are you sure you aren't doing
something elsewhere in the code that is locking the canvas?

Maybe you could also add some more trace info - is the unlock call
definitely being reached, and is the exception thrown the 1st time
round the loop or after a number of iterations?
--~--~---------~--~----~------------~-------~--~----~



Exception locking surface - lockCanvas() returns a null?

by mcmc » Thu, 09 Apr 2009 02:01:29 GMT


 The exception is thrown the 1st time around the loop. And Unlock is
never called, since there was never a successful Lock in the first
place... :(

Right now, my code looks like this one:
 http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/graphics/GLSurfaceView.html 

However, in the run() method, instead of having:

                if ((w > 0) && (h > 0)) {
                    /* draw a frame here */
                    mRenderer.drawFrame(gl);

                    /*
                     * Once we're done with GL, we need to call
swapBuffers()
                     * to instruct the system to display the rendered
frame
                     */
                    mEglHelper.swap();
                }

I modified it a little:

                               if ((w > 0) && (h > 0)) {
                                        mRenderer.drawFrame(gl);

                                        if (mRun){
                                                Canvas c = null;
                                                try {
                                                    mHolder = getHolder();      
//make sure holder is updated
                                                    c = mHolder.lockCanvas();
                                                    synchronized (mHolder) {
                                                        if (mMode == 
STATE_RUNNING && c != null){
                                                            doDraw(c);
                                                        }
                                                    }
                                                } 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) {
                                                        
mHolder.unlockCanvasAndPost(c);
                                                    }
                                                }
                                        }

                                         mEglHelper.swap();
                                }


On Apr 8, 4:04am, "ellipsoidmob...@googlemail.com"


--~--~---------~--~----~------------~-------~--~----~



Exception locking surface - lockCanvas() returns a null?

by ellipsoidmob...@googlemail.com » Thu, 09 Apr 2009 17:32:07 GMT


 I hadn't realised you are doing openGL stuff. I've used surfaceview/
holder in the same was as the lunarlander, but I haven't used openGL
so I don't know how that works.

But, at a glance, it looks like you've got a mix of two different
approaches here - maybe the lockcanvas/unlockcanvasandpost approach is
not appropriate when using openGL as the openGL code is controlling
and locking the surface?
--~--~---------~--~----~------------~-------~--~----~



Exception locking surface - lockCanvas() returns a null?

by mcmc » Fri, 10 Apr 2009 04:45:21 GMT


 wow thanks so much for your help. I think you're right! :D

however, now I run into another problem. Do you know how to convert
openGL to simply using the standard android/java 2D APIs?

On Apr 9, 2:31am, "ellipsoidmob...@googlemail.com"


--~--~---------~--~----~------------~-------~--~----~



Exception locking surface - lockCanvas() returns a null?

by mcmc » Sat, 11 Apr 2009 01:01:05 GMT


 thank you sooo much, everyone!
i've been meaning for someone to tell me that since a very long time
ago, but no one did, so i was stuck!

:)





--~--~---------~--~----~------------~-------~--~----~



Other Threads

1. ExpandableListAdapter not using fast scrolling, can't get it to show up.

I can't seem to get fast scrolling working with my `ExpandableListView`. 
What's more is that the `SectionIndexer` methods I have implemented in my 
adapter are never actually called and I have verified this via breakpoints.

Here is my activity:

    private void onCreate(Bundle a) {
         ...
         setContentView(R.layout.mylayout);
         ...
         setListAdapter(myAdapter);
         getExpandableListView().setFastScrollEnabled(true);
    }

Here's my layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
 <ExpandableListView android:id="@+id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fastScrollEnabled="true"/>
 <TextView android:id="@+id/android:empty"
android:text="EMPTY! DOOM!"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

Here's my adapter, which works by the way:


public class Adapter extends AbstractExpandableListAdapter<TTD, TTL>
implements SectionIndexer {

public static class TTDHolder {
TextView title;
}
 public static class TTLHolder {
TextView title;
ImageView icon;
}
 private final Pattern alphaMatch = Pattern.compile("^[a-zA-Z]$");
 private final Pattern numberMatch = Pattern.compile("^\\d$");
 private LayoutInflater inflater;
 public Adapter(Context context, int groupClosedView, int groupExpandedView, 
int childView,
List<Entry<TTD, List<TTL>>> objects) {
super(context, groupClosedView, groupExpandedView, childView, objects);
this.inflater = 
(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
 public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
TTDHolder holder;
 if (convertView != null) {
holder = (TTDHolder)convertView.getTag();
} else {
convertView = inflater.inflate(R.layout.item, parent, false);
 holder = new TTDHolder();
holder.title = (TextView) convertView.findViewById(R.id.item_title);
 convertView.setTag(holder);
}
 
holder.title.setText(this.getObjects().get(groupPosition).getKey().getName());
 return convertView;
}
 public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
TTLHolder holder;
 if (convertView != null) {
holder = (TTLHolder) convertView.getTag();
} else {
convertView = inflater.inflate(R.layout.item, parent, false);
 holder = new TTLHolder();
holder.title = (TextView) convertView.findViewById(R.id.item_title);
holder.icon = (ImageView) convertView.findViewById(R.id.item_icon);
 convertView.setTag(holder);
}
 holder.title.setText(this.getObjects().get(groupPosition).getValue()
.get(childPosition).getName());
 return convertView;
}

public Object[] getSections() {
return "*1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
}

public int getPositionForSection(int section) {
for (Entry<TTD, List<TTL>> entry : this.getObjects()) {
if (entry.getKey().getName().substring(0, 1) == getSections()[section])
return this.getObjects().indexOf(entry);
}
 return 0;
}

public int getSectionForPosition(int position) {
List<Object> sections = Arrays.asList(getSections());
return 
sections.indexOf(this.getObjects().get(position).getKey().getName().substring(0,
 
1).toUpperCase());
}
}

However, when I scroll, I never see the fast scroller show up, nor are the 
`SectionIndexer` methods ever actually called. Is there a minimum limit of 
items required for fast scroll?

-- 

2. Cannot write Exif data to JPG images

This doesn't work. Any ideas why?

ExifInterface exifInterface = new ExifInterface(filePath);

String o1 = exifInterface.readAttribute(TAG_ORIENTATION); //o1 is "0"

exifInterface.setAttribute(TAG_ORIENTATION, "90");
exifInterface.saveAttributes();

String o2 = exifInterface.readAttribute(TAG_ORIENTATION); //o2 is "90"

// relaunch app, read attribute for same photo

String o3 = exifInterface.readAttribute(TAG_ORIENTATION); //o3 is "0"
again, should be "90"

-- 

3. Trouble With WebView

4. Custom PathEffect

5. LiveWallpaper with SurfaceHolder.lockCanvas(Rect dirty)

6. AlertDialog and GLSurfaceView

7. Build broken after latest updates.