2011-01-14 25 views
6

Ho un elenco di punti di longitudine e di longitudine in un file xml che viene utilizzato in tutta la mia applicazione. Trovo che il mio io ripeta questo codice per ottenere punti spesso e penso che ci debba essere un modo migliore?Java/Android recupera matrice da xml

String[] mTempArray = getResources().getStringArray(R.array.stations); 
    int len = mTempArray.length; 
    mStationArray = new ArrayList<Station>(); 
    for(int i = 0; i < len; i++){ 
     Station s = new Station(); 
     String[] fields = mTempArray[i].split("[\t ]"); 
     s.setValuesFromArray(fields); 
     Log.i("ADD STATION", ""+s); 
     mStationArray.add(s); 
    } 

XML è nel formato:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <array name="stations"> 
     <item> 
      <name>Station name</name> 
      <longitude>1111111</longitude> 
      <latitude>11111</latitude> 
      <code>1</code> 
     </item> 

E un'altra (possibile) problema è che per ottenere una sola stazione che devo ottenere tutti loro e tirare quello che voglio dalla matrice . Sarà molto più lento? Posso rendere questo array coerente in tutta l'app? (Ma mantenendo la metodologia Intent separata)

risposta

4

ho avuto lo stesso pensiero come MilkJug, per usare un metodo di utilità per creare le stazioni, ma voglio offrire un approccio leggermente diverso: Spostare la maggior quantità di logica di costruzione il più possibile al costruttore Station di classe. Per mantenere l'esempio semplice, sto spostando il metodo di utilità nella classe Station.

Ciò fornisce un design generale più pulito, al di fuori della classe Station stessa, il codice non dovrebbe mai avere a che fare con un oggetto Station i cui passi di costruzione/inizializzazione non sono stati completati completamente.

(kgiannakakis's suggerimento di utilizzare un database può essere un modo migliore per andare se avete un sacco di oggetti stazione.)

public class Station { 
    private static List<Station> sStationArray = null; 

    /** 
    * Construct a Station from a specially-encoded String. The String 
    * must have all the necessary values for the Station, separated by tabs. 
    */ 
    public Station(String fieldString) { 
     String[] fields = fieldString.split("[\t ]"); 

     // For safety, setValuesFromArray() should be declared 'final'. 
     // Better yet, you could just move its body into this constructor. 
     setValuesFromArray(fields); 

     // I'm assuming 'mName' is the name field for the Station 
     Log.i("Station", this.mName); 
    } 

    public static Station getStationArray(Context ctx) { 
     if (sStationArray == null) { 

      // (Please don't use the prefix 'm' for non-member variables!) 
      final String[] tempArray = 
       ctx.getResources().getStringArray(R.array.stations); 
      final int len = tempArray.length; 

      // Passing the length into the ArrayList constructor (if it's 
      // known, or can be guessed at) can be a very simple yet 
      // effective optimization. In this case the performance boost 
      // will almost certainly **not** be meaningful, but it's 
      // helpful to be aware of it. 
      sStationArray = new ArrayList<Station>(len);  

      for (int i = 0; i < len; i++) { 
       Station s = new Station(tempArray[i]); 
       sStationArray.add(s); 
      } 
     } 
     return sStationArray; 
    } 
} 
+0

Grazie per questo. Sarebbe importante se lo avessi cambiato in un ArrayList? – Ashley

+0

È già un ArrayList - vedi la riga 'sStationArray = new ArrayList (len);'. È possibile che 'sStationArray' sia di tipo' ArrayList ', ma ciò non farebbe alcuna differenza in termini di funzionalità o prestazioni. –

4

Perché non creare un metodo di utilità che prende un contesto come parametro e restituisce le risorse della stazione? Per esempio:

public class StatUtil { 
    private static List<Station> mStationArray = null; 

    public static Station getStation(Context ctx) { 
    if (mStationArray == null) { 
     String[] mTempArray = getResources().getStringArray(R.array.stations); 
     int len = mTempArray.length; 
     mStationArray = new ArrayList<Station>(); 
     for(int i = 0; i < len; i++){ 
     Station s = new Station(); 
     String[] fields = mTempArray[i].split("[\t ]"); 
     s.setValuesFromArray(fields); 
     Log.i("ADD STATION", ""+s); 
     mStationArray.add(s); 
     } 
    } 

    return mStationArray; 
    } 
} 

e chiamare dal codice con:

stationArray = StatUtil.getStation(this); 

ripetutamente il recupero delle stazioni sarà più lento di loro cache, ma non significativamente più lento meno che non li recuperano in un ciclo. Fare come sopra impedirà il recupero di più copie.

+0

La chiamata a 'getResources()' deve essere preceduto da 'CTX. ' –

2

ho potuto proporre due soluzioni:

  1. Si potrebbe creare una classe Singleton che inizializza una volta, legge i dati dal XML e memorizza le stazioni in un elenco o una mappa. Utilizzare una mappa se si desidera trovare rapidamente una stazione in base al suo nome. La classe Singleton fornirà metodi per recuperare tutte le stazioni o solo una di esse.
  2. Creare una tabella di database e memorizzare le informazioni lì. Potresti aver bisogno di più codice, ma il vantaggio sarà che sarai in grado di eseguire query più avanzate.