2013-10-10 84 views
6

我有兩個Android項目,一個是主要項目(包名稱com.adip.sampler)和一個添加到主項目(包名稱com.samples.projb)的庫。在資源兩者我有相同密鑰的integer-arraymy_int_valuesAndroid資源關鍵衝突

在主要項目:

<integer-array name="my_int_values"> 
    <item>10</item> 
    <item>20</item> 
    <item>30</item> 
    <item>40</item> 
    <item>50</item> 
    <item>60</item> 
    <item>70</item> 
    <item>80</item> 
</integer-array> 

而在庫:

<integer-array name="my_int_values"> 
    <item>34</item> 
    <item>35</item> 
    <item>36</item> 
    <item>37</item> 
</integer-array> 

在主體工程從活動如果我正在調查這些陣列(主項目和庫)的值是什麼:

protected void showLocalStrings() { 
    Log.d("RESSampler", "In Main: " + Arrays.toString(getResources().getIntArray(com.adip.sampler.R.array.my_int_values))); 
    Log.d("RESSampler", "In Libr: " + Arrays.toString(getResources().getIntArray(com.samples.projb.R.array.my_int_values))); 
} 

然後我在logcat中看到的是:

In Main: [10, 20, 30, 40, 50, 60, 70, 80] 
In Libr: [10, 20, 30, 40, 50, 60, 70, 80] 

看來,主體工程覆蓋在文庫陣列中定義的值...如果我從正確的密鑰和資源閱讀我翻了一番檢查沒問題。直到我看了每個生成的R類。在主要的項目,這是我對com.adip.sampler.R.array.my_int_values

public static final class array { 
    public static final int my_int_values=0x7f060000; 
} 

而在庫項目com.samples.projb.R.array.my_int_values

public static final class array { 
    public static final int my_int_values = 0x7f060000; 
} 

的Android工具生成相同的值,所以難怪我得到這個行爲。如果我從其中一個整數數組中更改密鑰,我可以擺脫這種行爲,但想象一下,您有一些擁有大量資源和依賴庫的大型項目,遲早會碰到這種問題:擁有具有相同鍵值的相同類型的資源(我已使用stringstring-array進行了檢查,並且以上行爲也出現在此處)。所以問題是:

  1. 爲什麼會出現此問題?或者,如果這不是什麼問題解釋這種行爲?
  2. 如何避免它最好?我猜測,在定義密鑰方面嘗試具有某種獨特性會起到訣竅,但開發人員傾向於懶惰...

這出現使用多種最新的ADT和Eclipse版本(Juno和Indigo )。僅在Windows上進行檢查。

回答

8

Library Projects at Android Developers閱讀,有很多引用,他們明確地說合併發生在構建時間和具有相同ID的資源相互覆蓋。

對於其中資源ID在應用程序和 庫都定義從庫和應用

在例相同ID的資源,工具確保在 應用程序中聲明的資源得到優先權,並且圖書館項目 中的資源未編譯到應用程序.apk中。這使您的應用程序 可以靈活地使用或重新定義任何資源行爲或任何庫中定義的值。

對於具有相同ID的資源從兩個庫

...您的應用程序可以添加對多個庫項目,然後在 每個庫指定資源的相對優先級。這個 可讓您以累積方式建立應用程序中實際使用的資源。 當從應用程序 引用的兩個庫定義相同的資源ID時,工具將從優先級較高的庫中選擇資源,並丟棄另一個。

解決方案在文檔中建議

使用前綴來避免資源衝突

爲了避免公共資源的ID資源衝突,可以考慮使用 前綴或其他一致的命名方案,該方案是獨一無二的項目 (或在所有項目中都是唯一的)。

如何在圖書館從command line

如果要添加多個庫的引用設置優先級,請注意您可以 設置其相對優先級(與合併順序)手動編輯 項目。屬性文件並將每個引用的.n索引調整爲 合適。

+0

我害怕這是答案:)你碰巧知道Lint是否有意義檢測跨不同項目的重複資源ID? – gunar

+1

對此的評論「這給你的應用程序提供了靈活性,可以使用或重新定義在任何庫中定義的任何資源行爲或值,我真的沒有在這裏看到任何靈活性。如果Android使用主項目或優先級較高的項目中的資源並轉儲重複資源,那麼靈活性在哪裏? – gunar

+0

接受的答案,但StackOverflow允許我只在22小時內給予賞金。大頭針! – gunar

1

就我個人而言,我會更改資源的名稱。如果您閱讀了有關命名約定的任何內容,它應該是有意義的,「my_int_array」並不是太有用,特別是在其他人或項目可能使用的庫中。理想情況下,你希望能夠在6個月內忘掉它,回過頭來看看它,並且知道該數組對於/包含什麼,而不必鑽研代碼來推斷出什麼是數組,用它完成。

This post; https://stackoverflow.com/a/7249410/1222199在命名約定中包含幾個不同的答案。

最後,不清楚衝突,無法挖掘任何東西。我猜這是它自動生成的方式,可能值得記錄它作爲一個錯誤,並看看你是否得到任何來自開發團隊的迴應。

+0

我想你會意識到'my_int_array'這個項目是爲了這個問題的清晰度而編寫的。我正在處理一個擁有5個其他圖書館項目的巨大項目,每個項目都是擁有自己資源的另一箇中型項目。我正在尋找重複的資源密鑰,並更改使用這些密鑰的地方。但是,知道這是爲什麼,這將是一件很棒的事情。爲什麼構建系統不會在工作區/項目生態系統中生成唯一的鍵? – gunar

+0

是的,我喜歡。儘管如此,必須有一個更好的命名系統,以便它們具有獨特性,我目前的項目由10個獨立的項目組成,其中只有一些由我控制。我想象添加/刪除單個字符就足以改變密鑰。顯然,所使用的算法不適用於工作空間級別,僅適用於項目級別,因此建議將其記錄爲缺陷。誠實地說,這很可能會發生。事實上幾乎沒有關於此事的信息加強了這種情況發生的頻率。 – Trent