2017-08-31 65 views
2

问题

一个字段成员突然成为在Nexus 5X设备Android运行时一个空值私有成员变量在dispatchTouchEvent在Nexus 5X成为空

步骤已经采取

  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在我的实际的“方法1”的相当于从上面的简化类示例抛出。 我无法确定此变量将为空的任何有效情况,因为它在TestA构造函数中构造,并且如果构造失败,则不会有TestA实例调用“method1”。

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

有趣的潜在无关的Nexus 5X怪癖/错误

那里看来是对的Nexus 5X一个奇怪的现象:如果你的两根手指在一个单一的姿态在恰到好处的时尚汇集和保持在一起,数以千计触摸输入事件关闭。这发生在应用程序和主屏幕上,并不限于任何一个应用程序。这可能是相关的,或者它可能只是为复制做了足够的输入操作。

可能原因

  1. 序列化(变量可以被反序列化的空) - 类不被序列化
  2. 思考我的代码库 - 我不通过使用反射随时随地
  3. 思考东西外部???(即Android?)不知道是否有什么东西
  4. 内存损坏 - 这似乎是一个非常困难的Java应用程序
  5. 我的代码设置为null - 我只能访问字段成员在构造函数中
  6. 构造尚未完成时调用 方法 - 构造真的只是包含字段的setter,没有别的。方法被称为外部
  7. Android bug - 难以置信的不可能,但不能完全消除。
  8. ?????
+1

如果该字段被声明为“final”,问题是否会发生? – yegodm

+0

还没有能够验证,那是我目前正在采取的步骤,但我不明白这应该如何决定作为最终或不是,仍然只有一个写。 – Dan

+1

但是,Java存储器模型使得另一个可能会将非最终字段视为'null'的情况完全有可能。 – yegodm

回答

0

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