Pasar argumentos a AsyncTask y devolver resultados
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 encontrado que podría hacer esto con threads / handlers, pero no funcionó, y luego me enteré de la AsyncTask
.
En mi aplicación uso mapas con marcadores en él, y he implementado la función onTap para llamar a un método que he definido. El método crea un diálogo con 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>
a AsyncTask
(y trabajar con él allí), y cómo volver a un nuevo ArrayList<String>
como un resultado de AsyncTask
?
- Android seekbar establecer estilo personalizado con nueve imágenes de parche
- No puedo ver el progreso de spinner en ProgressDialog en Lollipop
- El diálogo de progreso no se muestra en la función onActivityResult
- ¿Cómo utilizar AsyncTask para mostrar un ProgressDialog mientras realiza un trabajo de fondo en Android?
- Cambio del mensaje de diálogo de progreso durante la ejecución
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);
Por lo tanto, como ves, me gustaría enviar la lista de matrices de cadenas "pasando" a AsyncTask
, y para obtener el resultado "cadena de array lista de nuevo de ella. 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(); }
Así que mi pregunta es cómo obtener los elementos de la lista de matrices "passing" en el método AsyncTask doInBackground
(y usarlos allí) y cómo devolver una lista de matrices para usarla en el método main (la lista de array "result").
- Android ExoPlayer onProgressChanged
- No FEATURE_INDETERMINATE_PROGRESS en ActionBarCompat para Android 2.3-
- ProgressDialog rechaza después de girar la pantalla
- Mostrar ProgressDialog mientras carga el diseño con setContentView
- Barra de progreso personalizada en Android?
- ProgressDialog Actividad de fondo Fade Out Animation
- FindViewById (android.R.id.progress) devuelve null
- show ProgressBar o Dialog de un IntentService para el progreso de la descarga
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 cambiar la implementación de tareas asíncronas
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 forma más sencilla 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);
¿Por qué pasarías un ArrayList? Debería ser posible llamar a ejecutar con los params directamente:
String curloc = current.toString(); String itemdesc = item.mDescription; new calc_stanica().execute(itemdesc, curloc)
¿Cómo funcionan los varrargs, verdad? Hacer un ArrayList para pasar la variable es trabajo doble.
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 la ArrayList por un booleano (éxito / fallo);
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í. Creo que es más fácil sobrecargar el constructor de la clase asychtask.
Public class calc_stanica extends 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 como: 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();
Esperando que ayude.