Pointer ids should be considered to be arbitrary non-negative integers. The framework currently makes some assumptions about the range of these ids, but applications must not, lest they be broken sometime in the future. Imagine a device that supports 60 simultaneous finger touches. It could happen. :)
Moreover, the order in which pointer ids are assigned is completely arbitrary. It happens to be the case that on most devices, the first pointer id assigned is 0. However the first pointer id could be anything. This is especially the case when the Honeycomb touch splitting feature is enabled (as it is by default for new applications). Suppose the user puts two fingers down within two different scrollable list views. The first finger might have id 0 and be delivered to a scrollable list view on the left. The second finger might have id 1 and be delivered to a scrollable list view on the right. From the perspective of the right hand list view, the first pointer id it received was 1, not 0. So I'm sad to say that many applications are making incorrect assumptions about pointer id values. One common bug is to conflate the meaning of the pointer id and pointer index values... crash! I strongly recommend that you track pointers using a sparse data structure like a map or android.util.SparseArray. Now let's talk about MotionEvent.ACTION_DOWN. The framework guarantees that motion events will always be delivered to a window in a consistent sequence: down/move/up, down/cancel, down/pointerdown/move/pointerup/up. However, the framework cannot work around buggy views that drop or corrupt part of the motion event stream before passing motion events down to their children. I've seen some custom views that do bad things like eat all multitouch events, or intercept some part of the gesture without canceling the rest. OnTouchListener implementations can also be problematic if they consume part but not all of a gesture. Views downstream may receive weird sequences of events as a result. As a defensive coding practice, views should be implemented to always reset themselves to a known ground state before handling ACTION_DOWN. In this way, they can recover in case some of their ancestor views fail to pass along the ACTION_UP or ACTION_CANCEL as would be expected. Likewise, bad things can happen during a gesture such as a pointer id mysteriously vanishing from the event without a an ACTION_POINTER_UP ever have been seen (because it was consumed somewhere else). Views should always check the result of MotionEvent.findPointerIndex and handle the case where a pointer went missing. Otherwise, the application may crash when it tries to access a pointer with index -1. Clearly if any of these things happen, there's a bug somewhere (probably in the app). It might not be very obvious though. With a little case, the app should be able to recover gracefully. Hope that helps, Jeff. On May 16, 12:58 pm, Mario Zechner <[email protected]> wrote: > A user reported an ArrayIndexOutOfBoundsException today in > ourmulti-touchhandler. We store x/y/touchState on a per pointer id basis in an > array. Dirty? Yes, but it worked on all devices so far. Usually > pointer ids are handed out like this: > > first finger goes down -> pointer Id 0 > second finger goes down -> pointer id 1 > second finger lifted > second finger goes down -> pointer id 1 > second finger lifted > second finger goes down -> pointer id 1 > > This works on all phones and some discussions in this group also point > out this exact behaviour. Sadly, MotionEvent is underdocumented so it > seems this was an assumption after all, not a rule all manufacturers > would follow. On the Sony Xperia Play the following behaviour is > observed. > > first finger goes down -> pointer Id 0 > second finger goes down -> pointer id 1 > second finger lifted > second finger goes down -> pointer id 2 > second finger lifted > second finger goes down -> pointer id 3 > > Is this a bug in the Xperia touch driver or is this actually wanted > behaviour? Did we all (and there are a couple of people i know of > having this issue) created faulty apps based on a wrong assumption? > > On a related note: The MotionEvent documentation has a new addition > which reads like this: > > "The view implementation should be prepared to handle ACTION_CANCEL > and should tolerate anomalous situations such as receiving a new > ACTION_DOWN without first having received an ACTION_UP for the prior > gesture." > > The handling of ACTION_CANCEL is a no-brainer of course. What is > making me a bit nervous is the fact that spurious ACTION_DOWN events > can now happen. It is not clear whether this will only happen if a > parent View consumed the accompanying ACTION_UP event or if this is > behaviour to be expected even in single View applications. > > Any pointers would be appreciated, no pun intended. -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en

