亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android主項目與Module中R類的區別詳解

發布時間:2020-10-23 16:15:57 來源:腳本之家 閱讀:173 作者:CPPAlien 欄目:移動開發

前言

大家都知道 Android 項目中會通過自動生成一個 R.java 類的方式來保存項目中所有資源文件的標識。在主項目中生成的 R.java 中的資源聲明是一個靜態常量,而在 module 中它卻是一個靜態變量。這是為什么呢?我們知道在 java 中如果某個值被聲明成常量(用 final 修飾),則在編譯后,該常量會被直接替換成值。而在 java 語法中,注解的屬性和 switch-case 中的 case 表達式,必須使用常量或者直接使用值,否則會報語法錯誤。

下面我們會展開討論下為什么 module 中的 R 類中聲明的資源標識不是 final 的,這些又導致了哪些現象?下面話不多說了,來一起看看詳細的介紹吧。

主項目中

比如你在主項目中創建了一個 activity_main.xml 的布局文件,則 R.java 中會自動加入一行如下靜態常量。

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

此后你就可以通過 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 ,會發現里面的靜態常量被直接替換成了值。代碼運行過程中,就可以直接通過值來找到對應資源了。

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

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

Module中

然后我們再在一個 module 中同樣創建一個 MainActivity 和對應的資源,我們查看該 module 下的 R.java 。

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

大家有發現區別了嗎?在 module 中添加的該資源少了 final。我們再來看下 MainActivity.class 文件。我們會發現此處的資源引用是使用的靜態變量方式,而未直接使用資源的值。

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

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

為什么這樣做

Android 中,如果你在 module 中添加了一個資源,就拿這里的 activity_main.xml 舉例。我們此處假設如果在 module 中也是 final 的,那會出現什么情況?第一,該 module 編譯后的代碼中該資源會被替換成值;第二,當該 module 被添加到主項目中后,如果主項目中有一個同樣名稱的資源,那么 module 中的該資源就會被替換;第三,主項目中會重新針對該資源生成一個 ID;最終就會出現 module 中那個資源 ID 找不到了。所以呢,這也是為什么 module 中的資源 ID 聲明不使用 final 的原因。

有關資源合并的規則,可以參考下 google 的官方文檔

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

導致的幾個現象

1,這就是為什么當主項目與 module 中有同樣資源時,module 卻會使用主項目的資源。

2,這也是為什么我們在 module 中無法針對資源使用 switch-case 方式的原因。

3,這也是為什么我們無法在 module 中直接使用 butterknife,因為注解的屬性需要是 final 的。當然現在 butterknife 已經提供了一個解決方案。就是利用 gradle 拷貝一份 R.java 命名成 R2.java,R2.java 里面的資源聲明都是 final 的。這樣就躲過了語法檢查。當然使用butterknife編譯后的字節碼中使用的還是R.java中的資源聲明。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

贡嘎县| 连江县| 平安县| 中方县| 和静县| 延川县| 名山县| 新安县| 苏尼特右旗| 玉环县| 兴义市| 莱州市| 涿鹿县| 伽师县| 新安县| 武胜县| 天镇县| 清丰县| 洛扎县| 南宫市| 东阳市| 南雄市| 宜兰市| 崇文区| 东乌| 固安县| 台安县| 涡阳县| 婺源县| 双鸭山市| 内乡县| 莱州市| 张家川| 蒙城县| 大连市| 大港区| 望谟县| 余姚市| 天津市| 台山市| 安国市|