1. 程式人生 > >Android java.lang.NoSuchFieldError: No static field xxx of type I in class Lcom/XX/R$id; or its superclasses

Android java.lang.NoSuchFieldError: No static field xxx of type I in class Lcom/XX/R$id; or its superclasses

activity oid 返回 反射 分享 -c lar 進行 是否

項目開發快到尾聲,突然發現之前一個模塊莫名其妙的奔潰了,我的內心也是奔潰的。以前一直都是好好的,也沒去動過它,為啥會出現這樣的問題呢? 下面我會根據自己的理解來看待問題

android是怎麽根據id查找到控件的

首先,你在調用 findViewById 之前,你必然是在 activity 中設置了 setContentView, 或者在 Fragment 中重載了 onCreatedView 方法,對於 findViewById, 他只能使用在 view或者 activity 下,對於 view, 你進行遍歷的根節點就是對應的 view, 對於 activity, 你對應的根節點就是你使用 setContentView 初始化的布局

當你調用 findViewById 是, android 先對比本身是否具有該 id,是則返回自己,不是則判斷自己是否為 ViewGroup, 如果是再對子視圖進行遍歷,否則返回 null, 遍歷時,按照從上到下的順序一一遍歷,只要找到一個節點的 id 為搜索的 id, 則返回這個節點代表的 view, 比如說你的 layout 中有兩個相同 id 的 view, 那麽返回的必然是最前的那一個

為什麽會出現這樣的情況

首先我們看看LOG日子

 java.lang.NoSuchFieldError: No static field tabTexts of type I in class
Lcom/xxx/R$id; or its superclasses (declaration of com.xxx.R$id appears in /data/data/com.sss/files/instant-run/dex/slice-slice_1-classes.dex)

這是關鍵問題,這裏告訴我們沒有找到tabTexts 的字段(ID),奇怪了,我也沒有碰過,為啥會突然出現這樣的問題。我們可以從這方面入手查找問題。

解決問題

上面說到了,調用findViewById 時會對相應的layout進行遍歷查找,如果沒有則返回null。同樣的NoSuchFieldError是Java反射中的一個異常,其表示無法通過反射找到需要的字段。進行到這裏,我們該考慮了,是不是加載的時候,不是加載了相應的layout。導致找不到tabTexts 的ID控件。於是全局搜索一下layout的名字,終於在這裏發現了弊端。我們來看看搜索結果:

技術分享

這裏我們可以發現,我滴天。怎麽會有兩個不同的ID,問題果然出現在這裏。項目在加載layout的時候,默認加載了0x7f0d01c6的ID,導致找不到tabTexts 。這下好解決了。BUG哪裏跑,看我還不消滅你。

解決辦法:
把custom_tab(就是報錯的layout)換一個名字。避免android加載錯誤的layout.

Android java.lang.NoSuchFieldError: No static field xxx of type I in class Lcom/XX/R$id; or its superclasses