最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android庫項目中的資源ID沖突的解決方法

 更新時間:2018年03月24日 09:15:21   作者:mmmmar  
本篇文章主要介紹了Android庫項目中的資源ID沖突的解決方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

1、前言

Android Studio對模塊化開發(fā)提供的一個很有用的功能就是可以在主項目下新建庫項目(Module),但是在使用庫項目時卻有一個問題就是資源ID沖突,因為編譯時SDK會自動幫我們處理這個問題,所以一般我們不會察覺到,但是在某些情況下,我們需要意識到這個問題的存在。

比如,在新建的庫項目中使用如下代碼:

public void onButtonClick(View view) {
  switch (view.getId()) {
    case R.id.button_1:
      break;
    case R.id.button_2;
      break;
  }
} 

IDE會提示:

Resource IDs cannot be used in a switch statement in Android library modules less. 
Validates using resource IDs in a switch statement in Android library module. Resource IDs are non final in the library projects since SDK tools r14, means that the library code cannot treat these IDs as constants.

再比如,我們在庫項目中以如下方式使用ButterKnife,編譯時就會報錯。

@OnClick(R.id.button_1)
public void onButtonClick(View view) { 

} 

 2、分析

無論是 switch 語句還是注解,都有一個要求就是使用的值必須是常量。在主項目中, R類中的成員變量都被 static final 修飾,而在庫項目中僅被 static 修飾。 

// 庫項目中生成的R類:
public final class R {
  public static final class id {
    public static int button_1 = 0x7f0c0001;
  }
}

// 主項目中生成的R類:
public final class R {
  public static final class id {
    public static final int text_1 = 2131165184;
  }
} 

為什么庫項目中生成的資源ID沒有被 final 修飾呢?官方解釋如下:

Non-constant Fields in Case Labels

當多個庫項目進行合并時,不同項目中的資源ID可能會重復。在ADT 14之前,無論是主項目還是庫項目,資源ID統(tǒng)一被定義為 final 類型的靜態(tài)變量。這樣照成的結果就是主項目進行編譯時一旦發(fā)現(xiàn)資源ID沖突,庫項目中對應的資源文件以及引用資源文件的代碼都需要重新編譯。

如果代碼中使用了被 static final 修飾的變量,那這個變量實際上就是一個常量,編譯時會直接使用它的值進行替換。在編譯時,如果庫項目與主項目的資源ID發(fā)生了重復,資源被分配了新的ID后庫項目之前編譯過的代碼也就失效了。

那么當庫項目R類中的變量僅被 static 修飾后會起到什么作用呢,我們可以看一下編譯后的字節(jié)碼再反編譯后的樣子。

// 主項目中的Activity:
public class MainActivity extends AppCompatActivity {
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 源代碼:setContentView(R.layout.activity_main);
    this.setContentView(2131296283);
  }
}

// 庫項目中的Activity:
public LibActivity extends AppCompatActivity {
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.activity_lib);
  }
} 

主項目R類中的資源ID被 static final 修飾,編譯時直接被替換成了對應的常量。庫項目R類中的資源ID僅被 static 修飾,所以保留了變量。這樣當資源ID發(fā)送沖突時,主項目R類不變,修改庫項目R類中的變量,庫項目已經(jīng)編譯過的代碼仍有效。

3、ButterKnife中的R2類

既然庫項目中的資源ID不可以定義為常量,那如何在庫文項目使用ButterKnife呢,作者提供了R2類供我使用。

@OnClick({R2.id.button_1, R2.id.button_2})
public void onButtonClick(View view) {
  int id = view.getId();
  if (id == R.id.button_1) {
    // ...
  } else if (id == R.id.button_2) {
    // ...
  }
} 

沒錯在注解中使用R2類,但是在代碼里還是需要使用R類,因為R類中的ID不是常量,所以只能使用 if 語句進行判斷。

先來看一下ButterKnife為我們生成的R2類與R類有什么不同: 

// 庫項目中的R類:
public final class R {
  public static final class id {
    public static int button_1 = 0x7f0c0001;
  }
}

// 庫項目中ButterKnife為我們生成的R2類:
public final class R2 {
  public static final class id {
    public static final int button_1 = 0x7f0c0001;
  }
}   

ButterKnife做的工作很簡單,僅僅是把R類中的變量搬到了R2類里,然后給所有的變量都加上了 final 。根據(jù)前面所說,當項目整體編譯時,庫項目的資源ID一旦與主項目的資源ID發(fā)送沖突,庫項目的資源會被重新分配ID導致其R類被修改。顯然這個過程并不涉及R2類,R2類中保留的仍然是過時的ID。但是ButterKnife提供的注解的作用是什么,它們并不是為了提供運行時信息,而是為了在編譯時生成代碼。

public class LibActivity_ViewBinding implements Unbinder { 
  private LibActivity target;
  private View view_button_1;
  private View view_button_2; 
  @UiThread
  public LibActivity_ViewBinding(final LibActivity target, View source) {
    this.target = target;
    View view = Utils.findRequiredView(source, R.id.button_1, "method 'onButtonClick'");
    this.view_button_1 = view;
    //view.setOnClickListener....
    view = Utils.findRequiredView(source, R.id.button_2, "method 'onButtonClick'");
    this.view_button_2 = view;
    //view.setOnClickListener....
  }
} 

在ButterKnife生成的代碼中,使用的仍然是R類。R2起到的作用僅僅是提供一個符號名,只要讓程序知道在生成代碼時對應哪一個變量即可。這個方法可以說是很“tricky”了。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 簡單實現(xiàn)Android文件上傳

    簡單實現(xiàn)Android文件上傳

    這篇文章主要為大家詳細介紹了如何簡單實現(xiàn)Android文件上傳的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • Kotlin中日志的使用方法詳解

    Kotlin中日志的使用方法詳解

    這篇文章主要給大家介紹了關于Kotlin中日志的使用方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • Android基于TextView實現(xiàn)的跑馬燈效果實例

    Android基于TextView實現(xiàn)的跑馬燈效果實例

    這篇文章主要介紹了Android基于TextView實現(xiàn)的跑馬燈效果,以完整實例形式分析了Android使用TextView通過屬性設置及功能代碼實現(xiàn)跑馬燈效果的相關技巧,需要的朋友可以參考下
    2016-02-02
  • 解決android studio 打開java文件 內(nèi)容全變了的問題

    解決android studio 打開java文件 內(nèi)容全變了的問題

    這篇文章主要介紹了解決android studio 打開java文件 內(nèi)容全變了的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • Android獲取內(nèi)置sdcard跟外置sdcard路徑

    Android獲取內(nèi)置sdcard跟外置sdcard路徑

    這篇文章主要介紹了Android獲取內(nèi)置sdcard跟外置sdcard路徑的相關資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • Android實現(xiàn)字母導航控件的示例代碼

    Android實現(xiàn)字母導航控件的示例代碼

    這篇文章主要介紹了通過自定義View實現(xiàn)字母導航控件的示例代碼,文中的實現(xiàn)過程講解詳細,對我們學習或工作有一定幫助,感興趣的可以學習一下
    2022-01-01
  • Android UI設計與開發(fā)之ViewPager仿微信引導界面以及動畫效果

    Android UI設計與開發(fā)之ViewPager仿微信引導界面以及動畫效果

    這篇文章主要為大家詳細介紹了Android UI設計與開發(fā)之ViewPager仿微信引導界面以及動畫效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Android利用RecyclerView實現(xiàn)列表倒計時效果

    Android利用RecyclerView實現(xiàn)列表倒計時效果

    這篇文章主要為大家詳細介紹了Android利用RecyclerView實現(xiàn)列表倒計時效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • Android自定義輪播圖效果

    Android自定義輪播圖效果

    這篇文章主要為大家詳細介紹了Android自定義輪播圖效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Android實現(xiàn)從activity中停止Service的方法

    Android實現(xiàn)從activity中停止Service的方法

    這篇文章主要介紹了Android實現(xiàn)從activity中停止Service的方法,結合實例形式簡單分析了Android中Service的注冊、創(chuàng)建及使用stopService停止Service的方法,需要的朋友可以參考下
    2016-01-01

最新評論

柳江县| 凌云县| 灵川县| 雷州市| 广灵县| 泸定县| 通州市| 芜湖县| 霍林郭勒市| 兴文县| 四平市| 浪卡子县| 逊克县| 宜兰市| 平凉市| 上思县| 汨罗市| 咸阳市| 林甸县| 和田市| 响水县| 赤峰市| 松溪县| 垫江县| 镇远县| 蒙山县| 庄浪县| 威海市| 海原县| 贵州省| 临桂县| 胶南市| 普定县| 衡水市| 红原县| 阿坝县| 探索| 抚州市| 泸定县| 大邑县| 呼图壁县|