NullPointerException en GestureDetector.onTouchEvent

Tengo una actividad usando un GestureDetector en onTouch. Dentro de mi diseño, también tengo una vista implementando un onClickListener. En Android ICS, obtengo una NullPointerException al manejar el TouchEvent. ¿Cuál es la causa de este error? He visto varios mensajes diciendo que onClick y onTouch no juegan bien juntos, pero no hay una explicación real de la causa o una solución real al problema, cuando se ve este error.

Aquí está el código:

public class FlipCardActivity extends Activity implements View.OnClickListener, View.OnTouchListener { protected GestureDetector gestureDetector; protected class TouchSwipeListener extends GestureDetector. SimpleOnGestureListener { @Override public boolean onDown(MotionEvent e) { return false; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // Calculate dx, gradient, velocity, etc // Check for and discard unacceptable swipes if (Math.abs(gradient) > SWIPE_MAX_GRADIENT || Math.abs(distance) < SWIPE_MIN_DISTANCE || Math.abs(velocity) < SWIPE_MIN_VELOCITY) return false; // Determine whether it's a left or a right swipe if (dx < 0) activity.showNext(); else activity.showPrevious(); return true; } } @Override protected void onCreate(Bundle savedInstance) { super.onCreate(savedInstance); gestureDetector = new GestureDetector(this, new TouchSwipeListener(this)); setContentView(R.layout.main); } @Override public boolean onTouch(View v, MotionEvent ev) { return gestureDetector.onTouchEvent(ev); } } 

Y el stacktrace es:

 java.lang.NullPointerException at android.view.GestureDetector.onTouchEvent(GestureDetector.java:587) at com.fivepumpkins.common.FlipCardActivity.onTouch(FlipCardActivity.java:602) at android.view.View.dispatchTouchEvent(View.java:5536) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:1957) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1726) at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1912) at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1371) at android.app.Activity.dispatchTouchEvent(Activity.java:2364) at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1860) at android.view.View.dispatchPointerEvent(View.java:5721) at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:2890) at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2466) at android.view.ViewRootImpl.processInputEvents(ViewRootImpl.java:845) at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2475) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4575) 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:789) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556) at dalvik.system.NativeStart.main(Native Method) 

En cuanto a la fuente ICS, puedo extraer la línea con el error: GestureDetector.java:587 . Ocurre dentro del método onTouchEvent() , en el caso de case MotionEvent.ACTION_UP: Aquí está el extracto:

 // Hold the event we obtained above - listeners may have changed the original. 586 mPreviousUpEvent = currentUpEvent; 587 mVelocityTracker.recycle(); 588 mVelocityTracker = null; 589 mIsDoubleTapping = false; 590 mHandler.removeMessages(SHOW_PRESS); 591 mHandler.removeMessages(LONG_PRESS); 592 break; 

Un NullPointerException en la línea 587 implica que mVelocityTracker es nulo. Este es el atributo VelocityTracker privado de la clase SimpleOnGestureListener . ¿Por qué esta variable sería nula en este punto?

Podría estar realmente relacionado con el oyente de clics. El GestureDetector, accede a mVelocityTracker y lo establece en null en MotionEvent.ACTION_UP y MotionEvent.ACTION_CANCEL. El escucha de clics se ejecuta en el método MotionEvent.ACTION_UP de onTouchEvent de la clase View. Hay quizá una relación (que no tengo tiempo para encontrar ahora) con los desencadenantes que ejecuta GestureDetector, al hacer clic, MotionEvent.ACTION_UP o MotionEvent.ACTION_CANCEL, después de que ya se haya establecido en null, por uno de estos, antes.

Intente eliminar el oyente de clics y ver si aún sucede. Si es así, es probable que sea mejor manejar todo en el oyente táctil.

También obtuve NPE en onTouchEvent() : 587. Así que empecé a usar GestureDetectorCompat de la biblioteca de soporte y funciona bien.

  • Android - Añadir GestureDetector a la vista web
  • Problemas con la detección de gestos en ListView
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.