【问题标题】:NullPointerException report from android market来自安卓市场的 NullPointerException 报告
【发布时间】:2011-05-12 13:02:28
【问题描述】:

一位用户提交了以下崩溃报告:

java.lang.NullPointerException
at android.widget.TextView.onTouchEvent(TextView.java:7202)
at android.view.View.dispatchTouchEvent(View.java:3778)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:886)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:886)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:886)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:886)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:886)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1716)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1124)
at android.app.Activity.dispatchTouchEvent(Activity.java:2125)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1700)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1822)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:5068)
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:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)

我无法在我的任何测试手机(Xperia、HTC Desire、Galaxy S)(或模拟器)上重现它,并且错误报告没有告诉我问题出在应用程序的哪个位置或在什么设备上(或者用户是谁,所以我可以向他们询问有关他们正在做什么导致它的更多信息)。我在代码中找不到明显尝试通过 findViewById 使用 TextView 而不首先检查它是否为空的任何地方。所有的 xml 文件都没有android:onclick,因此它不会尝试调用错误输入的函数或类似的东西。我尝试比较提供给 android 源的行,但它们似乎不直接匹配,并且读取命名方法的源并没有帮助我。 (免责声明:我只使用 Java 几个月。)

有人知道我还应该检查什么吗?


预计到达时间:这是我只有一个触摸监听器而不是点击监听器的地方:

btnDelete.setOnTouchListener(new View.OnTouchListener()
{
  public boolean onTouch(View v, MotionEvent meMotion)
  {
    int iAction = meMotion.getAction();

    switch (iAction)
    {
      case MotionEvent.ACTION_DOWN:
        if (false == bKeyPressed)
        {
          bKeyPressed = true;
          deleteANumber();
        }
        mHandler.removeCallbacks(mDeleteTouch);
        mHandler.postAtTime(mDeleteTouch, SystemClock.uptimeMillis()
          + BUTTON_DELAY);
        break;
      case MotionEvent.ACTION_UP:
        bKeyPressed = false;
        mHandler.removeCallbacks(mDeleteTouch);
        break;
    }

    return true;
  }
});

mDeleteTouch 在哪里

private final Runnable mDeleteTouch = new Runnable()
{
  public void run()
  {
    // delete a number from the display
    deleteANumber();

    // then call self in BUTTON_DELAY ms, unless cancelled
    mHandler.postAtTime(this, SystemClock.uptimeMillis() + BUTTON_DELAY);
  }
};

而 deleteANumber() 是

protected void deleteANumber()
{
  String strNumber = tvNumber.getText().toString();

  // only remove a character if there is at least one:
  if (strNumber.length() > 0)
  {
    strNumber = strNumber.substring(0, strNumber.length() - 1);
    tvNumber.setText(strNumber);
  }
}

这似乎可能是问题,因为您不能调用 null.length(),但创建 tvNumber 时其文本设置为“”,因此 getText().toString() 应始终返回非 null 值对吧?


ETA2 我设法在 HTC Desire HD 上遇到了同样的错误,但它似乎在没有返回我的代码的情况下崩溃了——在 onClick 内立即设置断点不会捕获任何东西.


ETA3如果我注释掉tvNumber.setInputType(InputType.TYPE_CLASS_NUMBER);,问题就会消失。

【问题讨论】:

  • 看起来更像是一个事件处理程序为空。您是否在任何地方将可能的 null 传递给 textview?
  • 不明显;我刚刚注意到我的 SQLite 数据库中的 datetime 字段没有像其他字段一样设置为不为空,所以我会仔细检查以防万一,但我也将它设置为所有插入的当前时间,所以它应该永远不会真正成为 null。
  • 处理程序本身不为空(这是允许的),而是您在 onTouchEvent 中所做的事情导致 NPE - 如果您没有覆盖 TextView 的 onTouchEvent 则可能组件中存在错误。你有没有问过用户这是在什么设备上?
  • 不幸的是,google anonymise 向 android market 报告,设备类型只显示“其他”。我无法与用户交谈。我确实为我的删除按钮设置了一个 OnTouchListener,但我返回 true,它应该消耗触摸,对吧?
  • @Joseph,实际上,它说“平台”是其他,而不是设备——根本没有提到设备——但无论哪种方式,我都不知道。

标签: java android nullpointerexception


【解决方案1】:

在 HTC Desire HD 上,触摸设置了 setInputType(InputType.TYPE_CLASS_NUMBER) 的 TextView 似乎会引发 NullPointerException。离开该设置可以防止崩溃,但需要手动输入过滤(这在我的情况下不是问题,但可能在其他人的情况下)。不是一个好的解决方案,但仍然是一个解决方案。

【讨论】:

  • 绝对正确,感谢您指出这一点。我们遇到了同样的问题,并且由于您的回答能够重现该错误。再次感谢!
  • 感谢您的更新。我发现通过在 XML 布局中指定 android:inputType="phone" 而不是在代码中解决问题(也与 TYPE_CLASS_PHONE 一起崩溃)。
【解决方案2】:

解决方法是不要在 TextView 中使用“setInputType”。无论如何,您都不需要对 TextViews 进行输入类型过滤,因为它们仅用于显示文本。 只有 EditText 需要输入类型(并且在那里有效)。我在 4.2 以下的 Android 版本上遇到了同样的问题。

缺点是,在文本视图上应用输入类型“密码”实际上是有意义的,因为它掩盖了密码,这可能是有意的(在我的情况下)。但这会在触摸 textview 时导致崩溃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    相关资源
    最近更新 更多