Android主項(xiàng)目和Module中R類(lèi)的區(qū)別

我們知道 Android 項(xiàng)目中會(huì)通過(guò)自動(dòng)生成一個(gè) R.java 類(lèi)的方式來(lái)保存項(xiàng)目中所有資源文件的標(biāo)識(shí)绰播。在主項(xiàng)目中生成的 R.java 中的資源聲明是一個(gè)靜態(tài)常量花枫,而在 module 中它卻是一個(gè)靜態(tài)變量刻盐。這是為什么呢掏膏?我們知道在 java 中如果某個(gè)值被聲明成常量(用 final 修飾),則在編譯后敦锌,該常量會(huì)被直接替換成值馒疹。而在 java 語(yǔ)法中,注解的屬性和 switch-case 中的 case 表達(dá)式乙墙,必須使用常量或者直接使用值颖变,否則會(huì)報(bào)語(yǔ)法錯(cuò)誤。下面我們會(huì)展開(kāi)討論下為什么 module 中的 R 類(lèi)中聲明的資源標(biāo)識(shí)不是 final 的听想,這些又導(dǎo)致了哪些現(xiàn)象腥刹?

主項(xiàng)目中

比如你在主項(xiàng)目中創(chuàng)建了一個(gè) activity_main.xml 的布局文件,則 R.java 中會(huì)自動(dòng)加入一行如下靜態(tài)常量汉买。

public static final class layout {
    ...
    public static final int activity_main=0x7f09001b;

此后你就可以通過(guò) R.layout.activity_main 的方式使用該資源

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

我們編譯上述代碼后得到 MainActivity.class 衔峰,會(huì)發(fā)現(xiàn)里面的靜態(tài)常量被直接替換成了值。代碼運(yùn)行過(guò)程中蛙粘,就可以直接通過(guò)值來(lái)找到對(duì)應(yīng)資源了垫卤。

public class MainActivity extends AppCompatActivity {
    public MainActivity() {
    }

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(2131296283);
    }
}

Module中

然后我們?cè)僭谝粋€(gè) module 中同樣創(chuàng)建一個(gè) MainActivity 和對(duì)應(yīng)的資源,我們查看該 module 下的 R.java 组题。

public static final class layout {
    ...
    public static int activity_main = 0x7f0f001c;

大家有發(fā)現(xiàn)區(qū)別了嗎葫男?在 module 中添加的該資源少了 final。我們?cè)賮?lái)看下 MainActivity.class 文件崔列。我們會(huì)發(fā)現(xiàn)此處的資源引用是使用的靜態(tài)變量方式,而未直接使用資源的值旺遮。

public class MainActivity extends AppCompatActivity {
    public MainActivity() {
    }

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(layout.activity_main);
    }
}

為什么這樣做

Android 中赵讯,如果你在 module 中添加了一個(gè)資源,就拿這里的 activity_main.xml 舉例耿眉。我們此處假設(shè)如果在 module 中也是 final 的边翼,那會(huì)出現(xiàn)什么情況?第一鸣剪,該 module 編譯后的代碼中該資源會(huì)被替換成值组底;第二,當(dāng)該 module 被添加到主項(xiàng)目中后筐骇,如果主項(xiàng)目中有一個(gè)同樣名稱(chēng)的資源债鸡,那么 module 中的該資源就會(huì)被替換;第三铛纬,主項(xiàng)目中會(huì)重新針對(duì)該資源生成一個(gè) ID厌均;最終就會(huì)出現(xiàn) module 中那個(gè)資源 ID 找不到了。所以呢告唆,這也是為什么 module 中的資源 ID 聲明不使用 final 的原因棺弊。

有關(guān)資源合并的規(guī)則晶密,可以參考下 google 的官方文檔

https://developer.android.com/studio/write/add-resources.html

導(dǎo)致的幾個(gè)現(xiàn)象

1模她,這就是為什么當(dāng)主項(xiàng)目與 module 中有同樣資源時(shí)稻艰,module 卻會(huì)使用主項(xiàng)目的資源。

2侈净,這也是為什么我們?cè)?module 中無(wú)法針對(duì)資源使用 switch-case 方式的原因尊勿。

3,這也是為什么我們無(wú)法在 module 中直接使用 butterknife用狱,因?yàn)樽⒔獾膶傩孕枰?final 的运怖。當(dāng)然現(xiàn)在 butterknife 已經(jīng)提供了一個(gè)解決方案。就是利用 gradle 拷貝一份 R.java 命名成 R2.java夏伊,R2.java 里面的資源聲明都是 final 的摇展。這樣就躲過(guò)了語(yǔ)法檢查。當(dāng)然使用butterknife編譯后的字節(jié)碼中使用的還是R.java中的資源聲明溺忧。

作者簡(jiǎn)介
彭濤(@彭濤me) 致力于讓技術(shù)變得易懂且有趣
個(gè)人博客:http://pengtao.me

簡(jiǎn)書(shū):http://www.reibang.com/u/f9246f41945e
GitHub:https://github.com/CPPAlien

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末咏连,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子鲁森,更是在濱河造成了極大的恐慌祟滴,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件歌溉,死亡現(xiàn)場(chǎng)離奇詭異垄懂,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)痛垛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)草慧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人匙头,你說(shuō)我怎么就攤上這事漫谷。” “怎么了蹂析?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵舔示,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我电抚,道長(zhǎng)惕稻,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任喻频,我火速辦了婚禮缩宜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己锻煌,他們只是感情好妓布,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著宋梧,像睡著了一般匣沼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上捂龄,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天释涛,我揣著相機(jī)與錄音,去河邊找鬼倦沧。 笑死唇撬,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的展融。 我是一名探鬼主播窖认,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼告希!你這毒婦竟也來(lái)了扑浸?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤燕偶,失蹤者是張志新(化名)和其女友劉穎喝噪,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體指么,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡酝惧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了伯诬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片系奉。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖姑廉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情翁涤,我是刑警寧澤桥言,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站葵礼,受9級(jí)特大地震影響号阿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鸳粉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一扔涧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦枯夜、人聲如沸弯汰。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)咏闪。三九已至,卻和暖如春摔吏,著一層夾襖步出監(jiān)牢的瞬間鸽嫂,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工征讲, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留据某,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓诗箍,卻偏偏與公主長(zhǎng)得像癣籽,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子扳还,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,099評(píng)論 25 707
  • 想想可能只是自己一時(shí)的荷爾蒙作祟才避,沖動(dòng)是魔鬼,我還是沒(méi)有能好好操控自己的情緒氨距。
    學(xué)到昏厥閱讀 100評(píng)論 0 0
  • 文/無(wú)憂(yōu)先生 你是我這一生最心愛(ài)的寶貝 看到你我會(huì)忘掉一切苦和累 當(dāng)你病了我看似無(wú)所謂 可我內(nèi)心的痛苦會(huì)超過(guò)你多少...
    無(wú)憂(yōu)先生閱讀 184評(píng)論 0 4
  • 我就是它桑逝,至于為什么不是“她”,哎你來(lái)牽牽我的手呀——牽不到吧俏让。 我是一只鬼楞遏。 你問(wèn)我長(zhǎng)什么樣?我可是黑長(zhǎng)直呢首昔,不...
    DoctorBlind閱讀 272評(píng)論 0 0