2

问题

在 Nexus 5x 设备上的 android 运行时,字段成员突然变为空值

已经采取的步骤

  1. 我已经验证在我的代码库、反射或其他方面没有对该字段的其他写入
  2. 我已经多次复制它,但只在 Nexus 5X 设备上。在其他设备上无法成功复制
  3. 我在 Nexus 5X 设备上发现了一个与我的应用程序无关的奇怪行为。

简化类示例:

public class TestA
{
    // While not final, could have been final as no writes other than in the constructor
    private Object impossibleToBeNull;

    public TestA()
    {
        impossibleToBeNull = new Object();
    }

    public void method1()
    {
        impossibleToBeNull.toString(); // Null pointer occurs here
    }
}

描述

不知何故,在我的 Android 应用程序运行时,一个 NullPointerException 被抛出在我上面简化类示例中的“method1”的实际等效项中。我无法确定该变量为空的任何有效情况,因为它是在 TestA 构造函数中构造的,并且如果它的构造失败,则不会有 TestA 实例可以调用“method1”。

我拥有的唯一附加信息是事件发生在 dispatchTouchEvent 上,特别是仅在 Nexus 5x 设备上(无法在其他设备上重现)。

有趣的可能无关的 Nexus 5X 怪癖/错误

Nexus 5x 上似乎有一种奇怪的行为,如果您将两根手指以一个手势放在一起并以正确的方式将它们握在一起,数以千计的触摸输入事件就会发生。这发生在应用程序内部和主屏幕上,并且不限于任何一个应用程序。这可能是相关的,或者它可能只是为再现做了足够的输入动作。

潜在原因

  1. 序列化(变量可以反序列化为 null) - 类永远不会序列化
  2. 我的代码库的 反射——我不在任何地方使用反射
  3. 外部事物的反射???(即android?)不确定是否有任何作用
  4. 内存损坏 - 这似乎在 Java 应用程序中很难做到
  5. 我的代码将其设置为 null - 我只在构造函数中访问该字段成员
  6. 调用方法时构造函数尚未完成 - 构造函数实际上只包含该字段的设置器,仅此而已。方法被外部调用
  7. Android 错误 - 极不可能,但无法完全消除。
  8. ???
4

1 回答 1

0

@yegodm对我的帖子的评论似乎是正确的。根据Oracle 文档,因为对我的“TestA”对象的引用是从另一个线程设置的,所以非最终成员可能尚未发布到主内存。他们的示例 17.5-1 很好地说明了这一点。

于 2017-08-31T17:28:20.060 回答