android - usando - Pasar argumentos a AsyncTask y devolver resultados
peticiones asincronas android (5)
¿Por qué pasaría un ArrayList? Debería ser posible simplemente ejecutar ejecutar con los parámetros directamente:
String curloc = current.toString();
String itemdesc = item.mDescription;
new calc_stanica().execute(itemdesc, curloc)
Que cómo funcionan los varrargs, ¿verdad? Hacer una ArrayList para pasar la variable es un trabajo doble.
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í sobre AsyncTask
.
En mi aplicación utilizo 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 una ArrayList<String>
a la AsyncTask
(y trabajar con ella allí), y cómo recuperar una nueva ArrayList<String>
como un resultado de la AsyncTask
?
El código del método se ve así:
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);
Entonces, como ve, me gustaría enviar la lista de arreglos de cadenas "pasando" a AsyncTask
, y obtener la lista de conjuntos de cadenas de "resultados" de vuelta. Y la clase calc_stanica AssycTask
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();
}
Entonces mi pregunta es cómo obtener los elementos de la lista de arreglos " AsyncTask doInBackground
" en el método AsyncTask doInBackground
(y usarlos allí), y cómo devolver una lista de arreglos para usar en el método principal (la lista de arreglos "resultado")?
Cambie su método para que se vea así:
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 cambie su implementación de 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 al contexto de inicio de la tarea, la manera más fácil sería anular onPostExecute en su lugar:
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);
En cierto modo 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 simplemente podría hacer que la lista de resultados sea un parámetro de clase y reemplazar ArrayList con un booleano (éxito / falla);
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
}
}
No lo hago así Me resulta más fácil sobrecargar el constructor de la clase asychtask.
la clase pública calc_stanica 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.*/ ... ...
Puede recibir resultados de retorno como ese: clase AsyncTask
@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;
}
recibir clase
_store.execute();
boolean result =_store.get();
Esperando que ayude.