PDA

Ver la Versión Completa : Pasar varios String de doInBackground a onPostExecute


Joakin60
04/06/16, 12:35:49
Cuando paso un solo String en una clase AsyncTask no tengo problemas:
protected String doInBackground(String... args) {
HashMap<String, String> params = new HashMap<String, String>();
params.put(TAG_PID, pidArte);
JSONObject json = jsonParser.makeHttpRequest(url_arte,
"POST", params);
try {
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
apartados = json.getJSONArray(TAG_APARTADOS);
for (int m = 0; m < apartados.length(); m++) {
JSONObject c = apartados.getJSONObject(m);
// Poner cada json item en una variable
String nombre = c.getString(TAG_NOMBRE);
return nombre;
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String nombre) {
pDialog.dismiss();
delegate.processFinish(nombre);
}
Pero cuando tengo que pasar varios string utilizo el siguiente código que fundamentalmente consiste en poner los string obtenidos de json en un HashMap<String, String> map, pasar el HashMap a onPostExecute y allí recuperar los valores de los string por su clave:
class ArteGeneralDetails extends AsyncTask<String, String, HashMap<String, String>> {

protected void onPreExecute() {

protected HashMap<String, String> doInBackground(String... args) {
HashMap<String, String> map = new HashMap<String, String>();
HashMap<String, String> params = new HashMap<String, String>();
params.put(TAG_PID, pidArte);
JSONObject json = jsonParser.makeHttpRequest(url_arte,
"POST", params);
try {
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
apartados = json.getJSONArray(TAG_APARTADOS);
for (int m = 0; m < apartados.length(); m++) {
JSONObject c = apartados.getJSONObject(m);
// Poner cada json item en una variable
String nombre = c.getString(TAG_NOMBRE_ARTE);
String icono2 = c.getString(TAG_IMAGEN_ARTE);
map.put(TAG_NOMBRE_ARTE, nombre);
map.put(TAG_IMAGEN_ARTE, icono2);
//return map;
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return map;
}
protected void onPostExecute(HashMap<String, String> resultados) {
pDialog.dismiss();
String nombre=resultados.get(TAG_NOMBRE_ARTE);
Toast.makeText(getApplicationContext(), nombre, Toast.LENGTH_LONG).show();
}
En el Toast no sale valor alguno para nombre.
Si alguien puede indicarme algo sobre cómo solucionarlo se lo agradecería.

Nonamed
04/06/16, 14:19:16
Joakin60:,

Movemos al subforo de desarrollo.

mocelet
04/06/16, 14:42:42
¿TAG_NOMBRE y TAG_NOMBRE_ARTE es lo mismo que le has cambiado el nombre?

Mira a ver si te está saltando la excepción del try-catch

Joakin60
04/06/16, 15:15:31
Lo primero gracias por responder.
Sí. Antes era:
//JSON Node names
private static final String TAG_NOMBRE = "nombre";
y ahora es:
private static final String TAG_NOMBRE_ARTE = "nombre";
Haciendo un debug en try salta de:
String icono2 = c.getString(TAG_IMAGEN_ARTE);
a:
catch (JSONException e)

Se come:
map.put(TAG_NOMBRE_ARTE, nombre);
map.put(TAG_IMAGEN_ARTE, icono2);

mocelet
04/06/16, 15:33:06
Pues ya lo tienes resuelto entonces, en el JSON no hay ningún atributo que se llame TAG_IMAGEN_ARTE y salta una excepción en el getString(). Bien porque has escrito mal la variable o porque realmente en el JSON no existe tal atributo.

Al contrario que en un Map que lo normal es devolver null si no existe, al leer de un JSON salta excepción, así que tienes que comprobar antes si existe el atributo con c.has(TAG_IMAGEN_ARTE). En caso de existir lo lees con c.getString igual y en caso de no existir ya queda a tu criterio (o le das un valor por defecto en plan "" o le das el valor null o simplemente no lo añades al hashmap)

Algo así:
String icono2 = c.has(TAG_IMAGEN_ARTE) ? c.getString(TAG_IMAGEN_ARTE) : null;

(eso es lo mismo que decir: si existe el atributo, léelo, si no dale el valor null)

Joakin60
04/06/16, 16:11:06
Efectivamente de nuevo, ha sido un empane, es:
private static final String TAG_IMAGEN_ARTE = "icono2";
en vez de:
private static final String TAG_IMAGEN_ARTE = "imagen";

Con esto ya tengo para rato y dejarte descansar, otra vez muchas gracias.
PD: Se me olvidaba, he leído buscando lo de HashMap, que en éste no se pueden poner valores que sean null, supongo que esto tiene fácil solución poniendo un condicional (if (valor!=null)).

mocelet
04/06/16, 16:38:06
Lo que no puede/debe ser null es la clave (tampoco es que tenga sentido que una key sea null porque tienen que ser únicas), el valor puede ser null perfectamente.

Otra cosa es para qué guardar algo cuyo valor es null, para eso mejor no guardarlo desde un principio.

Joakin60
04/06/16, 16:45:21
Es lo lógico, pero mira lo que he leido en:
http://jarroba.com/map-en-java-con-ejemplos/

Los elementos que inserta en el map no tendrán un orden específico. No aceptan claves duplicadas ni valores nulos.

mocelet
04/06/16, 17:01:19
Nuevamente, hablan de la clave, no del valor asociado a una clave. Puedes hacer un map.put("nombre", null) perfectamente. Cuando hagas get("nombre") te devolverá null.

Y, en efecto, no es que no se admitan duplicadas, es que cada vez que haces un put sustituyes el valor asociado a la clave que indiques. Puedes hacer un put("nombre", "adan") y acto seguido un put("nombre", "eva"), no te va a dar ningún error, pero cuando hagas el get("nombre") te devolverá "eva" que es lo último que guardaste con esa clave.

Joakin60
04/06/16, 17:03:45
Muy bien explicado. Gracias de nuevo.
Deberían haber dicho:
No aceptan claves duplicadas ni claves nulos.