2014-10-02 84 views
2

我想知道更好的方法來提高我的程序的性能。目標是自動加載資源,我使用字符串或字符串數​​組元素的名稱。舉例來說,如果我有下一個資源:自動獲取資源 - Android

<string name="temperature">temperature</string> 
<string name="pressure">pressure</string> 
<string name="velocity">velocity</string> 
... 

<string-array name="measures"> 
    <item>@string/temperature</item> 
    <item>@string/pressure</item> 
    <item>@string/velocity</item> 
    ... 
</string-array> 

<string name="name_temperature">Temperature</string> 
<string name="name_pressure">Pressure</string> 
<string name="name_velocity">Velocity</string> 
... 

<string-array 
    name="name_measures"> 
    <item>@string/name_temperature</item> 
    <item>@string/name_pressure</item> 
    <item>@string/name_velocity</item> 
    ... 
</string-array> 

<string-array name="units_temperature"> 
    <item>K</item> 
    <item>°C</item> 
    <item>°F</item> 
    <item>R</item> 
</string-array> 

我加載資源,這種方式:

measuresMap = new HashMap<String, String>(); 

String[] measures = getResources().getStringArray(R.array.measures); 

for(int i = 0; i < measures.length; i++){ 
    measuresMap.put(measures[i], getResources().getString(getResources().getIdentifier("name_" + measures[i], "string", getActivity().getPackageName())).toString()); 
} 

即我是從「措施」,以將其映射的字符串數組值是相應的字符串'name_ <>'。

我使用微調來選擇度量,例如,「溫度」:

measureSpinner = (Spinner) view.findViewById(R.id.spinnerConverter); 
setSpinner(measureSpinner, R.array.name_measures, android.R.layout.simple_spinner_item, android.R.layout.simple_spinner_dropdown_item); 

當選擇的項目中,一種方法檢索來自地圖視的項的字符串中的關鍵微調(getKeyByValueFromMap從here):

String[] units = getResources().getStringArray(getResources().getIdentifier("units_" + getKeyByValueFromMap(measuresMap, measureSpinner.getSelectedItem().toString()), "array", getActivity().getPackageName())); 

public <T, E> T getKeyByValueFromMap(Map<T, E> map, E value) { 
    for (Map.Entry<T, E> entry : map.entrySet()) { 
     if (value.equals(entry.getValue())) { 
      return entry.getKey(); 
     } 
    } 
    return null; 
} 

我需要這樣做來填充NumberPicker:

String[] units = getResources().getStringArray(getResources().getIdentifier("units_" + getKeyByValueFromMap(measuresMap, measureSpinner.getSelectedItem().toString()), "array", getActivity().getPackageName())); 

我認爲這在某種程度上是低效的。我讀了一些關於使用TypedArray加載數組的內容。我想到了一個多維的String數組。目標是相同的:自動加載資源(由for循環驅動以填充Map)。 HashMap是最佳選擇嗎?

<string name="@string/temp">Temperature</string> 

回答

1

每當我讀到一個關於性能的問題,在我的腦海鐘聲響起,詢問是否有一個真正的性能問題:如果資源名稱可能與其他資源字符串被定義會更容易些。如果你使用少量的值,你將不會注意到任何糟糕的表現。如果你使用大量數據,你應該使用sqlite代替。

如果你不會使用@字符串/ name_temperature本身,它可以直接在陣列上,並使其類似的documentation

的例子是的,你可以利用TypedArray

TypedArray measures = context.getResources().obtainTypedArray(R.array.name_measures); 

它理解length()getString(index)

回到你的代碼,我不太瞭解你在這裏需要一個地圖,除非你真的擔心把字符串直接放在你的數組中而不是ID。

此外,我看到你使用名稱來生成微調器的ID;在這種情況下,這對性能沒有幫助,更重要的是,它並沒有使代碼更清晰。

所以真正的答案: 我會參考紡紗廠的地方訪問。這可能是很好的,需要一個不同的密鑰,並且創建一個Spinner子類,它可以將索引位置轉換爲我想要的字符串。換句話說,委託Spinner負責存儲位置並將其轉換爲字符串。由於在這裏我確實需要將位置映射到字符串(而不是僅僅是ID),所以我可以使用一個簡單的String [],然後,只需訪問該位置,創建所需的字符串,或將其設置爲選中狀態(然後當你向你的Spinner詢問它的價值時,你可以詢問它的選定值,記住你現在有一些屬性的參考)。