2010-11-16 27 views
34

Tengo una aplicación que hace algunos cálculos largos, y me gustaría mostrar un diálogo de progreso mientras esto se hace. Hasta ahora he descubierto que podía hacer esto con hilos/manipuladores, pero no funcionó, y luego descubrí el AsyncTask.Pasar argumentos a AsyncTask, y devolver resultados

En mi aplicación uso mapas con marcadores, y he implementado la función onTap para llamar a un método que he definido. El método crea un diálogo con los botones Sí/No, y me gustaría llamar a AsyncTask si se hace clic en Sí. Mi pregunta es cómo pasar un ArrayList<String> al AsyncTask (y trabajar con él allí), y cómo obtener un nuevo ArrayList<String> como resultado del AsyncTask?

El código del método es similar a esto:

String curloc = current.toString(); 
String itemdesc = item.mDescription; 

ArrayList<String> passing = new ArrayList<String>(); 
passing.add(itemdesc); 
passing.add(curloc); 

ArrayList<String> result = new ArrayList<String>(); 

new calc_stanica().execute(passing,result); 

String minim = result.get(0); 
int min = Integer.parseInt(minim); 

String glons = result.get(1); 
String glats = result.get(2); 

double glon = Double.parseDouble(glons); 
double glat = Double.parseDouble(glats); 

GeoPoint g = new GeoPoint(glon, glat); 
String korisni_linii = result.get(3); 

Así que, como ves, me gustaría enviar la cadena serie de listas de "pasar" a la AsyncTask, y para obtener la cadena "número" una lista de arreglos desde allí. Y la clase calc_stanica AssycTask se ve así:

public class calc_stanica extends AsyncTask<ArrayList<String>, Void, ArrayList<String>> { 
    ProgressDialog dialog; 

    @Override 
    protected void onPreExecute() { 
     dialog = new ProgressDialog(baraj_mapa.this); 
     dialog.setTitle("Calculating..."); 
     dialog.setMessage("Please wait..."); 
     dialog.setIndeterminate(true); 
     dialog.show(); 
    } 

    protected ArrayList<String> doInBackground(ArrayList<String>... passing) { 

     //Some calculations... 

     return something; //??? 
    } 

    protected void onPostExecute(Void unused) { 
     dialog.dismiss(); 
    } 

Así que mi pregunta es cómo conseguir que los elementos del "paso" lista de arreglo en el método AsyncTask doInBackground (y usarlos allí), y la forma de devolver una lista de arreglo usar en el método principal (la lista de matriz "resultado")?

Respuesta

61

cambiar su método a tener este aspecto:

String curloc = current.toString(); 
String itemdesc = item.mDescription; 
ArrayList<String> passing = new ArrayList<String>(); 
passing.add(itemdesc); 
passing.add(curloc); 
new calc_stanica().execute(passing); //no need to pass in result list 

y cambiar su aplicación tarea asíncrona

public class calc_stanica extends AsyncTask<ArrayList<String>, Void, ArrayList<String>> { 
ProgressDialog dialog; 

    @Override 
    protected void onPreExecute() { 
     dialog = new ProgressDialog(baraj_mapa.this); 
     dialog.setTitle("Calculating..."); 
     dialog.setMessage("Please wait..."); 
     dialog.setIndeterminate(true); 
     dialog.show(); 
    } 

    protected ArrayList<String> doInBackground(ArrayList<String>... passing) { 
     ArrayList<String> result = new ArrayList<String>(); 
     ArrayList<String> passed = passing[0]; //get passed arraylist 

     //Some calculations... 

     return result; //return result 
    } 

    protected void onPostExecute(ArrayList<String> result) { 
     dialog.dismiss(); 
     String minim = result.get(0); 
     int min = Integer.parseInt(minim); 
     String glons = result.get(1); 
     String glats = result.get(2); 
     double glon = Double.parseDouble(glons); 
     double glat = Double.parseDouble(glats); 
     GeoPoint g = new GeoPoint(glon, glat); 
     String korisni_linii = result.get(3); 
    } 

UPD:

Si desea tener acceso a la tarea de iniciar contexto, la forma más fácil sería anular onPostExecute in place:

new calc_stanica() { 
    protected void onPostExecute(ArrayList<String> result) { 
     // here you have access to the context in which execute was called in first place. 
     // You'll have to mark all the local variables final though.. 
    } 
}.execute(passing); 
+0

Gracias por su respuesta, pero tengo una cosa más para preguntar. Si defino int min = Integer.parseInt (minim); por ejemplo, en la clase AsyncTask onPostExecute(), ¿cómo puedo acceder desde mi método de clase principal? Cuando lo cambio así, aparece el error "no se puede resolver" en el método de la clase principal. –

+2

@Bojan Ilievski: Simplemente haz que tu variable mínima sea global. – Wroclai

+0

Gracias a ambos por sus respuestas nuevamente, he resuelto mis problemas ... –

12

¿Por qué pasaría una ArrayList? Debería ser posible ejecutar sólo llamar con los parametros directamente:

String curloc = current.toString(); 
String itemdesc = item.mDescription; 
new calc_stanica().execute(itemdesc, curloc) 

que la forma en varrargs trabajo, ¿verdad? Hacer una ArrayList para pasar la variable es un trabajo doble.

+0

Estoy totalmente de acuerdo con Leander aquí. De todos modos para cambiar la marca de verificación de la respuesta correcta? –

4

Estoy de acuerdo con Leander en este caso.

llamada:

new calc_stanica().execute(stringList.toArray(new String[stringList.size()])); 

tarea:

public class calc_stanica extends AsyncTask<String, Void, ArrayList<String>> { 
     @Override 
     protected ArrayList<String> doInBackground(String... args) { 
      ... 
     } 

     @Override 
     protected void onPostExecute(ArrayList<String> result) { 
      ... //do something with the result list here 
     } 
} 

O usted podría hacer que la lista de resultados de un parámetro de clase y reemplazar el ArrayList con un valor lógico (éxito/fracaso);

public class calc_stanica extends AsyncTask<String, Void, Boolean> { 
     private List<String> resultList; 

     @Override 
     protected boolean doInBackground(String... args) { 
      ... 
     } 

     @Override 
     protected void onPostExecute(boolean success) { 
      ... //if successfull, do something with the result list here 
     } 
} 
1

I dont do it like this. Me resulta más fácil sobrecargar el constructor de la clase asychtask.

calc_stanica clase pública se extiende AsyncTask>

String String mWhateveryouwantToPass; 

public calc_stanica(String whateveryouwantToPass) 
{ 

    this.String mWhateveryouwantToPass = String whateveryouwantToPass; 
} 
/*Now you can use whateveryouwantToPass in the entire asynchTask ... you could pass in a context to your activity and try that too.*/ ... ... 
0

Usted puede recibir devolver resultados como que: AsyncTask clase

@Override 
protected Boolean doInBackground(Void... params) { 
    if (host.isEmpty() || dbName.isEmpty() || user.isEmpty() || pass.isEmpty() || port.isEmpty()) { 
     try { 
      throw new SQLException("Database credentials missing"); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
    } 

    try { 
     Class.forName("org.postgresql.Driver"); 
    } catch (ClassNotFoundException e) { 
     e.printStackTrace(); 
    } 

    try { 
     this.conn = DriverManager.getConnection(this.host + ':' + this.port + '/' + this.dbName, this.user, this.pass); 
    } catch (SQLException e) { 
     e.printStackTrace(); 
    } 

    return true; 
} 

clase de recepción:

_store.execute(); 
boolean result =_store.get(); 

la esperanza de que t ayudará.

Cuestiones relacionadas