開發之中遇到:
Android java.lang.NoSuchFieldError: No static field xxx of type I in class Lcom/XX/R$id; or its superclasses
仔細查找對應ID后,確認對應ID和頁面並沒有問題,全局搜索發現有同名的layout文件在不同的module下,但是各用各的,正常來說並不會有什么問題。
根據仔細搜索及排查,從下面了解這個問題:
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 。
解決辦法:
custom_tab(就是報錯的layout)換一個名字。避免android加載錯誤的layout.
by: yzl
