1

I wrote a simple MotionEvent exercise in which all I do is log the parameters of the event. I do that by implementing OnTouchListener and overriding onTouch() in the main activity.

For one button, I return true at the end of onTouch(). No problems there.

For another button, I return false at the end of onTouch(). This is where it gets interesting. By mere returning 'false', a FATAL EXCEPTION is thrown with a tiny hint which I don't really understand: "recycled twice!".

What does this mean?

Update: per the suggestion in the comment below, I am adding the details of the exception from LogCat:

03-08 10:35:14.275: ERROR/AndroidRuntime(521): FATAL EXCEPTION: main
03-08 10:35:14.275: ERROR/AndroidRuntime(521): java.lang.RuntimeException: MotionEvent{405215b0 action=0 x=66.0 y=78.0 pressure=1.0 size=0.0} recycled twice!
03-08 10:35:14.275: ERROR/AndroidRuntime(521):     at android.view.MotionEvent.recycle(MotionEvent.java:659)
03-08 10:35:14.275: ERROR/AndroidRuntime(521):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1880)
03-08 10:35:14.275: ERROR/AndroidRuntime(521):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-08 10:35:14.275: ERROR/AndroidRuntime(521):     at android.os.Looper.loop(Looper.java:123)
03-08 10:35:14.275: ERROR/AndroidRuntime(521):     at android.app.ActivityThread.main(ActivityThread.java:3647)
03-08 10:35:14.275: ERROR/AndroidRuntime(521):     at java.lang.reflect.Method.invokeNative(Native Method)
03-08 10:35:14.275: ERROR/AndroidRuntime(521):     at java.lang.reflect.Method.invoke(Method.java:507)
03-08 10:35:14.275: ERROR/AndroidRuntime(521):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
03-08 10:35:14.275: ERROR/AndroidRuntime(521):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
03-08 10:35:14.275: ERROR/AndroidRuntime(521):     at dalvik.system.NativeStart.main(Native Method)
Regex Rookie
  • 10,432
  • 15
  • 54
  • 88

1 Answers1

4

Are you recycling and then passing false?

The framework will assume that the MotionEvent is still valid if you return false and will do its own processing with it.

From the docs:

Recycle the MotionEvent, to be re-used by a later caller. After calling this function you must not ever touch the event again.

Matthew
  • 44,826
  • 10
  • 98
  • 87
  • I think that the answer to your question is Yes: In addition to onTouch in the main activity, I override onTouchEvent() in subclassed buttons. Only when onTouch() returns false, onTouchEvent() gets called, and that onTouchEvent() ends with **event.recycle(); return false;** Am I not allowed to return false after event.recycle()? Where can I learn more about this? – Regex Rookie Mar 08 '11 at 17:01
  • 1
    Try the docs link I posted for more info. Yes, you should not call event.recycle() if you're going to return false, because the framework will send the same MotionEvent to another listener after yours. – Matthew Mar 08 '11 at 17:02
  • Thanks for making this clear. The docs link contains only one line about recycle()... The guys at Google must be assuming that all Android developers are all geniuses. :) – Regex Rookie Mar 08 '11 at 17:08
  • hehe, yep. Although the error message you got was what tipped me off. – Matthew Mar 08 '11 at 17:12