Getting Reports of MotionEvent Recycled Twice

HimeAnator

Member
Licensed User
Longtime User
I got a report from a user saying that he received an error. the error was "android.view.MotionEvent.recycle".

with this info:

B4X:
java.lang.RuntimeException: MotionEvent { action=ACTION_UP, id[0]=0, x[0]=282.98486, y[0]=253.53613, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=5730554, downTime=5730342, deviceId=2, source=0x1002 } recycled twice!
at android.view.MotionEvent.recycle(MotionEvent.java:1659)
at android.view.ViewRootImpl.finishMotionEvent(ViewRootImpl.java:3031)
at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3022)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2582)
at android.view.ViewRootImpl.processInputEvents(ViewRootImpl.java:887)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2591)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4722)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
at dalvik.system.NativeStart.main(Native Method)

checked the forums and saw that the workaround was adding CallSubDelayed. But by looking at this error code I'm not too sure what part of my program code I need to fix. I have a bitmap two line listview on the main activity of my app and when they add a new item an "add new" activity is called and I close the main activity. once the user enters the info for the new item they hit a "save" button and the proper text files are updated and the main activity is restarted reading in all of the new data and the "add new" activity closes. Not sure if any part on doing all of that causing the issue. Any help on this would be appreciated.
 
Last edited:

HimeAnator

Member
Licensed User
Longtime User
I'm using version 2.50 and I only use ItemClick not ItemLongClick. The only fix I have tried so far is adding the CallSubDelayed to the item click event and all other buttons that switch between activities. Was that what I should do? I am still waiting to hear back from the user to see if that fixed it. I am unable to get the error on my device.
 
Upvote 0

HimeAnator

Member
Licensed User
Longtime User
Could It have possibly been the button code that switches between the activities or the "Save" button that adds a new item to the list? I have added the CallSubDelayed to just about all of the buttons and click events. Is that what you would suggest doing? Is this error usually thrown for just buttons and click events? I have not gotten any more reports of the error and I'm not sure how to replicate it myself. Seems to be an isolated problem with just a few devices :/
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
Interesting. I was seeing a few of these exceptions showing up on Play Store for my Yahtzee app. I had used the Reflection library to define click event handlers for some label views that were being loaded into arrays & the event handlers also have modal dialogs in them. I guess at the time, I didn't realize that I could just specify a common event handler for multiple views in the designer... I have now done so & eliminated the need to use the Reflection library for this purpose, so I'll see how it goes from here.
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
Nope - it seems that removing the Reflection library hasn't fixed the issue. The frustrating thing about this is that it doesn't seem to give any hint as to where in the code the error is occurring, or what version of Android the user's device is on:

B4X:
java.lang.RuntimeException: MotionEvent { action=ACTION_UP, id[0]=0, x[0]=246.25546, y[0]=143.37213, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=54580428, downTime=54580318, deviceId=3, source=0x1002 } recycled twice!
at android.view.MotionEvent.recycle(MotionEvent.java:1659)
at android.view.ViewRootImpl.finishMotionEvent(ViewRootImpl.java:2918)
at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:2909)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2477)
at android.view.ViewRootImpl.processInputEvents(ViewRootImpl.java:845)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2486)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4429)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:3151)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:2918)
at dalvik.system.NativeStart.main(Native Method)

Any ideas? Anyone?
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
Hi Erel,

There are only 2 places I use Reflector now. The first is in my Main activity module to get the version number of the app...

B4X:
Sub Get_Version
    Dim pm As PackageManager
    Dim sVersion As String
    Dim r As Reflector
    Dim p As String
   
    p = r.GetStaticField("anywheresoftware.b4a.BA", "packageName")
    sVersion = pm.GetVersionName(p)
    lblVersion.Text = "Version: " & sVersion & " " & sRelease
End Sub

And the second is in the Create sub of my NetConnect service module. The code is setting up to start a UDP multicast...

B4X:
Sub Service_Create
    Tablet.Target = Tablet.GetContext
    Tablet.Target = Tablet.RunMethod2("getSystemService", "wifi", "java.lang.String")
    Tablet.Target = Tablet.RunMethod2("createMulticastLock", "mylock", "java.lang.String")
    Tablet.RunMethod2("setReferenceCounted", False, "java.lang.boolean")    'not really necessary but safer
    Tablet.RunMethod("acquire")                                            'acquire the lock
End Sub

Neither of these code blocks use reflection to define event handlers, nor do they use modal dialogs. From ~20K installs, I've only seen 11 occurrences of this exception, so it's not a major issue - but I'd like to be able to track it down & fix it if I can.

Thanks - Colin.
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
Sorry - forgot to say that the "Tablet" object in Service_Create is a Reflector object declared in Process_Globals...
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
Yeah - I didn't think it was.

Apart from about 6 menu items, I have 4 touch (_Click) events:

1) The roll button (btnRoll_Click);
2) An array of imageviews that holds the 5 dice imageviews from the layout (arDice_Click);
3) An array of labels that holds the left score labels from the layout (Left_Score_Click);
4) An array of labels that holds the right score labels from the layout (Right_Score_Click);

The code from each of them is quite long, so you probably don't want me to post it here - however they all do various processing & the btnRoll_Click, Left_Score_Click & Right_Score_Click all post a MsgBox under certain circumstances. Looking at the x,y coordinates reported in the various exception messages, it looks like it might be the labels that are generating the error.

I haven't seen it for over a week now, so maybe I got my versions mixed up & was fixed. The last time it happened was in v7.8 & I'm at v8.2 now, so I'll give keep an eye on it & see if it happens again.

Thanks - Colin.
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
OK - if I see it again, I'll do that. I'd like to better understand why this issue comes up though, & why using CallSubDelayed resolves it. Can you shed some light?

Thanks - Colin.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
This issue shouldn't happen normally. It was introduced in Android v4.04 and fixed in B4A v1.92.

It happened when a modal dialog was displayed (or a debug pause) blocking the event completion. The solution was to use a method similar to CallSubDelayed to raise the event. The B4A event is then raised after the native event completed.

This is why the Touch event is safe and the reflection TouchListener is not safe.

I don't remember seeing any other reports of this issue so it is hard to say why it happens here.
 
Upvote 0
Top