2011-01-14 16 views
6

Tengo una lista de puntos de longitud y longitud en un archivo xml que se utiliza en toda mi aplicación. Me encuentro repitiendo este código para obtener puntos a menudo y creo que debe haber una manera mejor.Java/Android obtener matriz de 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 está en el formato de:

<?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> 

Y otra (posible) El problema es que para obtener sólo una estación Tengo que llegar a todos ellos y tirar de la que yo quiero de la matriz . ¿Esto va a ser considerablemente más lento? ¿Puedo hacer que esta matriz sea consistente en toda la aplicación? (Pero manteniendo la metodología de intención separada)

Respuesta

4

que tenían el mismo pensamiento que MilkJug, utilizar un método de utilidad para crear las estaciones, pero quiero ofrecer un enfoque ligeramente diferente: se mueven tanto de la lógica de la construcción de lo posible en el constructor Station clase. Para mantener el ejemplo simple, también moveré el método de utilidad a la clase Station.

Esto proporciona un diseño global más limpio, ya que fuera de la clase Station, su código nunca debería tener que tratar con un objeto Station cuyos pasos de construcción/inicialización no se han completado completamente.

(kgiannakakis's sugerencia de utilizar una base de datos puede ser un mejor camino a seguir si usted tiene una gran cantidad de objetos de la estación.)

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

Gracias por esto. ¿Importaría si lo cambiara a una ArrayList? – Ashley

+0

Ya es una ArrayList: consulte la línea 'sStationArray = new ArrayList (len);'. Puede cambiar 'sStationArray' para que sea del tipo' ArrayList ', pero eso no haría ninguna diferencia en la funcionalidad o el rendimiento. –

4

¿Por qué no crear un método de utilidad que toma un contexto como parámetro y devuelve los recursos de la estación? Por ejemplo:

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; 
    } 
} 

y llamaremos a partir de su código con:

stationArray = StatUtil.getStation(this); 

repetidamente ir a buscar las estaciones será más lento que el almacenamiento en caché, pero no significativamente más lenta a menos que les esté recogiendo en un bucle. Hacer lo anterior evitará que se obtengan copias múltiples.

+0

La llamada a 'getResources()' tiene que llevar el prefijo 'CTX. ' –

2

pude proponer dos soluciones:

  1. Se puede crear una clase Singleton que inicializa una vez, lee los datos del XML y almacena las estaciones en una lista o un mapa. Use un mapa si desea encontrar rápidamente una estación en función de su nombre. La clase Singleton proporcionará métodos para recuperar todas las estaciones o solo una de ellas.
  2. Crea una tabla de base de datos y almacena la información allí. Es posible que necesite más código, pero la ventaja será que podrá ejecutar consultas más avanzadas.