在 Codename One iOS 应用程序上调查 Java.Lang.NullPointerException
Investigate Java.Lang.NullPointerException on a Codename One iOS app
今天我试图调查这个问题:https://github.com/codenameone/CodenameOne/issues/2975
我在这里写信是想问我如何才能准确找到问题所在。这个错误令人沮丧。
基本上,仅在 iOS 上,我遇到了这个错误,它是在随机使用应用程序后发生的:
java.lang.NullPointerException
at com_codename1_ui_Form.pointerReleased:3758
at net_informaticalibera_cn1_simpleapi_OuterForm.pointerReleased:360
at com_codename1_ui_Component.pointerReleased:4679
at com_codename1_ui_Display.handleEvent:2289
at com_codename1_ui_Display.edtLoopImpl:1214
at com_codename1_ui_Display.mainEDTLoop:1132
at com_codename1_ui_RunnableWrapper.run:120
at com_codename1_impl_CodenameOneThread.run:176
at java_lang_Thread.runImpl:153
我重写了pointerReleased
方法,看看x
和y
是否是抛出前一个异常时可接受的值,看起来是这样:
@Override
public void pointerReleased(int x, int y) {
try {
super.pointerReleased(x, y);
} catch (Exception ex) {
Log.p("OuterForm.pointerReleased ERROR, x->" + x + ", y->" + y + ", https://github.com/codenameone/CodenameOne/issues/2975");
Log.e(ex);
SendLog.sendLogAsync();
}
}
使用该覆盖,相当于崩溃保护功能,在第一次发生此异常后,TextArea
组件不再可用:点击它们不会打开 VKB。
简而言之,Form.pointerReleased
的iOS端口里面有一个NullPointerException
:如何发现该方法的哪一行抛出异常?我希望找到有助于解决错误的信息。
问题是classForm
的方法public void pointerReleased(int x, int y)
的代码都在try... finally
里面,隐藏了异常的实际原因。
为了找出实际原因,我在我的应用程序的 BaseForm
class 中使用了以下覆盖,它扩展了 Form
并且我将其用作所有其他表单的 superclass :
@Override
public void pointerReleased(int x, int y) {
try {
Component cmp = instance.getResponderAt(x, y);
if (cmp != null) {
cmp.pointerReleased(x, y);
}
} catch (Exception ex) {
Log.p("BaseForm.pointerReleased ERROR, x->" + x + ", y->" + y + ", https://github.com/codenameone/CodenameOne/issues/2975");
Log.e(ex);
SendLog.sendLogAsync();
}
}
正如预期的那样,这给了我错误的实际原因,即在 TextArea
actionListener 的 lambda 表达式中:更具体地说,问题是 revalidate
[=18] =] 在某些情况下可以是 null
的引用(奇怪的是,这只发生在 iOS 上)。在那之后,我删除了以前的覆盖(破坏了一些功能),我修复了我的代码以防止 null
对象(具有 if
条件)上的 revalidate
并且错误消失了(我已通过长时间使用该应用程序进行了测试)。
今天我试图调查这个问题:https://github.com/codenameone/CodenameOne/issues/2975 我在这里写信是想问我如何才能准确找到问题所在。这个错误令人沮丧。
基本上,仅在 iOS 上,我遇到了这个错误,它是在随机使用应用程序后发生的:
java.lang.NullPointerException
at com_codename1_ui_Form.pointerReleased:3758
at net_informaticalibera_cn1_simpleapi_OuterForm.pointerReleased:360
at com_codename1_ui_Component.pointerReleased:4679
at com_codename1_ui_Display.handleEvent:2289
at com_codename1_ui_Display.edtLoopImpl:1214
at com_codename1_ui_Display.mainEDTLoop:1132
at com_codename1_ui_RunnableWrapper.run:120
at com_codename1_impl_CodenameOneThread.run:176
at java_lang_Thread.runImpl:153
我重写了pointerReleased
方法,看看x
和y
是否是抛出前一个异常时可接受的值,看起来是这样:
@Override
public void pointerReleased(int x, int y) {
try {
super.pointerReleased(x, y);
} catch (Exception ex) {
Log.p("OuterForm.pointerReleased ERROR, x->" + x + ", y->" + y + ", https://github.com/codenameone/CodenameOne/issues/2975");
Log.e(ex);
SendLog.sendLogAsync();
}
}
使用该覆盖,相当于崩溃保护功能,在第一次发生此异常后,TextArea
组件不再可用:点击它们不会打开 VKB。
简而言之,Form.pointerReleased
的iOS端口里面有一个NullPointerException
:如何发现该方法的哪一行抛出异常?我希望找到有助于解决错误的信息。
问题是classForm
的方法public void pointerReleased(int x, int y)
的代码都在try... finally
里面,隐藏了异常的实际原因。
为了找出实际原因,我在我的应用程序的 BaseForm
class 中使用了以下覆盖,它扩展了 Form
并且我将其用作所有其他表单的 superclass :
@Override
public void pointerReleased(int x, int y) {
try {
Component cmp = instance.getResponderAt(x, y);
if (cmp != null) {
cmp.pointerReleased(x, y);
}
} catch (Exception ex) {
Log.p("BaseForm.pointerReleased ERROR, x->" + x + ", y->" + y + ", https://github.com/codenameone/CodenameOne/issues/2975");
Log.e(ex);
SendLog.sendLogAsync();
}
}
正如预期的那样,这给了我错误的实际原因,即在 TextArea
actionListener 的 lambda 表达式中:更具体地说,问题是 revalidate
[=18] =] 在某些情况下可以是 null
的引用(奇怪的是,这只发生在 iOS 上)。在那之后,我删除了以前的覆盖(破坏了一些功能),我修复了我的代码以防止 null
对象(具有 if
条件)上的 revalidate
并且错误消失了(我已通过长时间使用该应用程序进行了测试)。