NullPointerException in GestureDetector.onTouchEvent

核能气质少年 提交于 2019-12-10 02:31:18

问题


I have an activity using a GestureDetector in onTouch. Inside my layout, I also have a view implementing an onClickListener. On Android ICS, I get a NullPointerException while handling the TouchEvent. What is the cause of this error? I have seen several posts saying that onClick and onTouch don't play well together but no real explanation of the cause or a real solution to the problem, when one sees this error.

Here is the code:

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);
    }
}

And the stacktrace is:

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)

Looking at the ICS Source, I can extract the line with the error: GestureDetector.java:587. It happens inside the onTouchEvent() method, in the case case MotionEvent.ACTION_UP:. Here is the excerpt:

// 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;

A NullPointerException in Line 587 implies that mVelocityTracker is null. This is the private VelocityTracker attribute of the SimpleOnGestureListener class. Why would this variable be null at this point?


回答1:


It could be indeed related with the click listener. The GestureDetector, accesses mVelocityTracker and sets it to null in MotionEvent.ACTION_UP and MotionEvent.ACTION_CANCEL. The click listener is executed in the MotionEvent.ACTION_UP of onTouchEvent method of View class. There's maybe a relation (which I don't have time to find now) with triggers that the GestureDetector executes, on click, MotionEvent.ACTION_UP or MotionEvent.ACTION_CANCEL, after it has been already set to null, by one of these, before.

Try removing the click listener and see if it still happens. If yes, you are probably better handling everything in the touch listener.




回答2:


I also got NPE in onTouchEvent():587. So I started using GestureDetectorCompat from support library and it works fine.



来源:https://stackoverflow.com/questions/11376956/nullpointerexception-in-gesturedetector-ontouchevent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!