2017-08-31 66 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很好地顯示了這一點。