У меня есть действие, использующее GestureDetector в onTouch. Внутри моего макета у меня также есть представление, реализующее onClickListener. В Android ICS я получаю исключение NullPointerException при обработке события TouchEvent. В чем причина этой ошибки? Я видел несколько сообщений, в которых говорилось, что onClick и onTouch плохо работают вместе, но нет реального объяснения причины или реального решения проблемы, когда вы видите эту ошибку.
Вот код:
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);
}
}
И трассировка стека:
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)
Глядя на исходный код ICS, я могу извлечь строку с ошибкой:GestureDetector.java:587
. Это происходит внутри метода onTouchEvent()
, в случае case MotionEvent.ACTION_UP:
. Вот отрывок:
// 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;
NullPointerException
в строке 587 означает, что mVelocityTracker
равно нулю. Это закрытый атрибут VelocityTracker
класса SimpleOnGestureListener
. Почему эта переменная должна быть нулевой в этот момент?