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

Reply via email to