10

onTouch で GestureDetector を使用するアクティビティがあります。レイアウト内には、onClickListener を実装するビューもあります。Android ICS で、TouchEvent の処理中に NullPointerException が発生します。このエラーの原因は何ですか? 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の Aは、それmVelocityTrackerが null であることを意味します。これは、クラスのプライベートVelocityTracker属性です。SimpleOnGestureListenerこの時点でこの変数が null になるのはなぜですか?

4

2 に答える 2

1

実際、クリックリスナーに関連している可能性があります。GestureDetector は mVelocityTracker にアクセスし、MotionEvent.ACTION_UP と MotionEvent.ACTION_CANCEL で null に設定します。ViewクラスのonTouchEventメソッドのMotionEvent.ACTION_UPでクリックリスナーを実行します。おそらく、GestureDetector がクリック時に MotionEvent.ACTION_UP または MotionEvent.ACTION_CANCEL のいずれかによって null に設定された後に実行されるトリガーとの関係 (今は見つけることができません) があるかもしれません。

クリック リスナーを削除してみて、それでも発生するかどうかを確認してください。はいの場合は、タッチ リスナーですべてを処理した方がよいでしょう。

于 2012-07-08T12:57:28.467 に答える