View.onTouchEvent()中无法解释的异常

时间:2012-01-02 11:52:57

标签: android nullpointerexception ontouchevent

几周前,我在Android Market上发布了我的第一款游戏。在beta测试期间一切都很好,但最近我收到了几个这样的错误:

java.lang.NullPointerException
 at towe.papersoccer.GameView.onTouchEvent(GameView.java:166)
 at android.view.View.dispatchTouchEvent(View.java:3819)
 at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
 at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
 at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
 at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1907)
 at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1159)
 at android.app.Activity.dispatchTouchEvent(Activity.java:2086)
 at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1891)
 at android.view.ViewRoot.handleMessage(ViewRoot.java:1811)
 at android.os.Handler.dispatchMessage(Handler.java:99)
 at android.os.Looper.loop(Looper.java:123)
 at android.app.ActivityThread.main(ActivityThread.java:4632)
 at java.lang.reflect.Method.invokeNative(Native Method)
 at java.lang.reflect.Method.invoke(Method.java:521)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:871)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
 at dalvik.system.NativeStart.main(Native Method)

以下是抛出异常的方法代码:

// This class extends View

private PointF  anchor;
private PointF  holder;

public boolean onTouchEvent(MotionEvent e) {
    if (e.getAction() == MotionEvent.ACTION_DOWN) {
        anchor = new PointF(e.getX(), e.getY());
        holder = new PointF(anchor.x, anchor.y);
        return true;
    } else if (e.getAction() == MotionEvent.ACTION_MOVE) {
        holder.x = e.getX();
        holder.y = e.getY();
        return true;
    } else if (e.getAction() == MotionEvent.ACTION_UP) {
        float length = PointF.length(holder.x-anchor.x, holder.y-anchor.y);
        if (length > 20) {
            int row = 0;
            int column = 0;
            if (holder.x == anchor.x) {
                if (holder.y > anchor.y) {
                    row = 1;
                } else {
                    row = -1;
                }
            } else {
                float a = (holder.y-anchor.y)/(holder.x-anchor.x);
                if (holder.x > anchor.x) {
                    if (a > 1/2.5) row = 1;
                    else if (a < -1/2.5) row = -1;
                    if (a > -2.5 && a < 2.5) column = 1;
                } else {
                    if (a > 1/2.5) row = -1;
                    else if (a < -1/2.5) row = 1;
                    if (a > -2.5 && a < 2.5) column = -1;
                }
            }
            row += current.row;
            column += current.column;
            move(row, column, true); // As you can see in stack trace, this method doesn't throw the exception
        }
        anchor = null;
        holder = null;
        return true;
    }
    return false;
}

我不知道为什么在某些设备上这个方法会抛出NullPointerException。我想这是因为他们有时可能不会使用MotionEvent.ACTION_DOWN调用此方法,因此 anchor holder 未定义......但它是否可能?我找不到可以解释异常的任何其他原因。

希望你能帮助我,对不起我的语言错误,Towe。

1 个答案:

答案 0 :(得分:0)

anchorholder仅在第一个if语句(带MotionEvent.ACTION_DOWN的语句)中分配了值。 因此,如果分支(anchorholder)在尝试分配时导致NPE,则其他== nullMotionEvent.ACTION_MOVE都会被取消分配(MotionEvent.ACTION_UP)访问holder.xholder.y, anchor.x or anchor.y`。