![]() |
|
| Programación y Desarrollo para Android Subforo exclusivo para temas de programación de software para PDAs y desarrollo de aplicaciones, interfaces, etc bajo Android |
«
Tema Anterior
|
Siguiente tema
»
|
|
Herramientas |
|
#1
|
||||
|
||||
|
como recibir un string directo de un asynctask .execute(url);
A ver la cosa es que tengo este codigo que voy a enseñar primero y despues comento:
Código:
new AlertDialog.Builder(MainActivity.this)
.setIcon(R.drawable.que)
.setTitle("¿ Que desea hacer ?")
.setMessage(dataList.get(position).get(KEY_NOMBRE))
.setPositiveButton("CANCELAR", new DialogInterface.OnClickListener() {
@override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "Cancelado", Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("EXPULSAR", new DialogInterface.OnClickListener() {
@override
public void onClick(DialogInterface dialog, int which) {
//new GetUrl().execute(URL+"/?accion=expulsar&uuid="+dataList.get(position).get(KEY_UUID));
if(resp.equals("ExpOK")) {
Toast.makeText(MainActivity.this, "¡ Residente Expulsado !", Toast.LENGTH_SHORT).show();
}
}
})
.setNeutralButton("BANEAR", new DialogInterface.OnClickListener()
{
@override
public void onClick(DialogInterface dialog, int which)
{
//new GetUrl().execute(URL+"/?accion=banear&uuid="+dataList.get(position).get(KEY_UUID));
if(resp.equals("BanOK")) {
Toast.makeText(MainActivity.this, "¡ Residente Baneado !", Toast.LENGTH_SHORT).show();
}
}
})
.show();
Código:
//new GetUrl().execute(URL+"/?accion=expulsar&uuid="+dataList.get(position).get(KEY_UUID)); Código:
String resp = new GetUrl().execute(URL+"/?accion=expulsar&uuid="+dataList.get(position).get(KEY_UUID)); |
|
|
|
#2
|
||||
|
||||
|
Respuesta corta: No puedes, porque no puedes recibir una respuesta síncrona de algo asíncrono, y menos aún en el hilo principal.
Respuesta larga: El código que procesa la respuesta de la tarea asíncrona debe ir en el "onPostExecute" del AsyncTask, que para eso está. Puedes hacer algo elaborado, como pasar un listener (en este caso una interfaz creada por ti) como parámetro al GetUrl y que el onPostExecute del GetUrl ejecute un método presente en ese listener, así podrías implementarlo al crear cada GetUrl. Respuesta adicional: Para tareas relacionadas con HTTP lo mejor es usar una librería, yo uso la Volley de Google, otros prefieres la OkHttp de Square. Yo uso Volley precisamente por ser de Google . La mayoría de estas librerías (Volley lo hace) ofrecen ya listeners para las respuestas HTTP, tanto para las positivas (2XX) como para las negativas (cualquier otra respuesta o fallo en la conexión, en este último caso un 0)
|
|
#3
|
||||
|
||||
|
Gracias por responder kriogeN.
Mira, he intentado hacer otra cosa, mi codigo del MainActivity es: [PHP] public class MainActivity extends AppCompatActivity { ArrayList<HashMap<String, String>> dataList = new ArrayList<HashMap<String, String>>(); static final String KEY_AVATAR = "avatar"; // parent node static final String KEY_NOMBRE = "nombre"; static final String KEY_UUID = "uuid"; static final String KEY_THUMB_URL = "foto"; ListView listView; ProgressBar loading; String URL; String resp; // A project by Ferdousur Rahman Shajib, Founder of www.androstock.com private DownloadData downloadData = new DownloadData(); @override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = (ListView)findViewById(R.id.listHome); loading = (ProgressBar)findViewById(R.id.emptyElement); listView.setEmptyView(loading); downloadData = new DownloadData(); downloadData.execute(); } private class DownloadData extends AsyncTask<String, Void, Document> { @override protected void onPreExecute() { super.onPreExecute(); } Document doc = null; protected Document doInBackground(String... args) { //URL = "http://www.myurl.com"; URL = "http://www.myurl.com"; try{ XMLParser parser = new XMLParser(); String xml = parser.getXmlFromUrl(URL+"/?accion=getAvatars"); // getting XML from URL doc = parser.getDomElement(xml); // getting DOM element }catch (Exception e) { Log.d("Exception", e.getMessage()); } return doc; } @override protected void onPostExecute(Document doc) { try{ XMLParser parser = new XMLParser(); NodeList nl = doc.getElementsByTagName(KEY_AVATAR); for (int i = 0; i < nl.getLength(); i++) { HashMap<String, String> map = new HashMap<String, String>(); Element e = (Element) nl.item(i); map.put(KEY_NOMBRE, parser.getValue(e, KEY_NOMBRE)); map.put(KEY_UUID, parser.getValue(e, KEY_UUID)); map.put(KEY_THUMB_URL, "http://www.myurl.com/image/"+parser.getValue(e, KEY_THUMB_URL)+"/1"); dataList.add(map); } IsoAdapter adapter = new IsoAdapter(MainActivity.this, dataList); listView.setAdapter(adapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @override public void onItemClick(AdapterView<?> adapt, View view, final int position, long id) { // TODO Auto-generated method stub new AlertDialog.Builder(MainActivity.this) .setIcon(R.drawable.que) .setTitle("¿ Que desea hacer ?") .setMessage(dataList.get(position).get(KEY_NOMBRE) ) .setPositiveButton("CANCELAR", new DialogInterface.OnClickListener() { @override public void onClick(DialogInterface dialog, int which) { Toast.makeText(MainActivity.this, "Cancelado", Toast.LENGTH_SHORT).show(); } }) .setNegativeButton("EXPULSAR", new DialogInterface.OnClickListener() { @override public void onClick(DialogInterface dialog, int which) { httpHandler handler = new httpHandler(); String resp = handler.post(URL,"expulsar",dataList.get(position) .get(KEY_UUID).toString()); Toast.makeText(MainActivity.this, resp, Toast.LENGTH_LONG).show(); //new GetUrl().execute(URL+"/?accion=expulsar&uuid="+dataList.get(position).get (KEY_UUID)); if(resp.equals("ExpOK")) { Toast.makeText(MainActivity.this, "¡ Residente Expulsado !", Toast.LENGTH_SHORT).show(); } } }) .setNeutralButton("BANEAR", new DialogInterface.OnClickListener() { @override public void onClick(DialogInterface dialog, int which) { httpHandler handler = new httpHandler(); String resp = handler.post(URL,"banear",dataList.get(position).g et(KEY_UUID).toString()); Toast.makeText(MainActivity.this, resp, Toast.LENGTH_LONG).show(); //new GetUrl().execute(URL+"/?accion=banear&uuid="+dataList.get(position).get(K EY_UUID)); if(resp.equals("BanOK")) { Toast.makeText(MainActivity.this, "¡ Residente Baneado !", Toast.LENGTH_SHORT).show(); } } }) .show(); //Toast.makeText(getApplicationContext(), // "Click: " + dataList.get(position).get(KEY_NOMBRE), Toast.LENGTH_LONG) // .show(); } }); }catch (Exception e) { Log.d("Exception", e.getMessage()); } } } } [/PHP] y en el httpHandler.class tengo esto: [PHP] public class httpHandler { public String post(String posturl, String var1, String var2){ try { HttpClient httpclient = new DefaultHttpClient(); /*Creamos el objeto de HttpClient que nos permitira conectarnos mediante peticiones http* HttpPost httppost = new HttpPost(posturl); /*El objeto HttpPost permite que enviemos una peticion de tipo POST a una URL especificada* //AÑADIR PARAMETROS List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("accion",var1)); params.add(new BasicNameValuePair("uuid",var2)); /*Una vez añadidos los parametros actualizamos la entidad de httppost, esto quiere decir en pocas palabras anexamos los parametros al objeto para que al enviarse al servidor envien los datos que hemos añadido* httppost.setEntity(new UrlEncodedFormEntity(params)); /*Finalmente ejecutamos enviando la info al server* HttpResponse resp = httpclient.execute(httppost); HttpEntity ent = resp.getEntity();/*y obtenemos una respuesta* String text = EntityUtils.toString(ent); return text; } catch(Exception e) { return "error";} } } [/PHP] la cosa es que me responde error siempre, cual es el error ? Mi idea es hacer lo de esta web, http://codigoprogramacion.com/tag/an...2#.V7jtME2LTIV Alguien me puede ayudar ? |
|
#4
|
||||
|
||||
|
El código de la web que enlazas es un despropósito por varios motivos (principalmente uso de funciones de red en el hilo principal que por eso te lanza siempre una excepción, también por el uso de las extintas bibliotecas Apache).
kriogeN te lo explicó muy bien, hazle caso. Las peticiones de red son asíncronas (se hacen en segundo plano) para no bloquear el hilo principal de ejecución. Cualquier cosa que necesites hacer con esos datos tienes que hacerlos donde te avise la biblioteca que uses (normalmente un listener) o si es una async task, en su onPostExecute. "Directamente" es imposible porque las peticiones de red llevan tiempo y si haces un respuesta = obtenerURL(....) se quedaría bloqueado hasta conectarse al servidor, que es una pésima experiencia de usuario. Android impone que el acceso a Internet se haga en segundo plano (asíncrono) para evitar malas prácticas. Última edición por mocelet Día 21/08/16 a las 12:09:51 |
|
#5
|
||||
|
||||
|
tukymix, como te ha dicho mocelet el código hoy en día no funcionaría en ningún dispositivo Android, tu error radica en usar como ejemplo un código que hoy en día no es correcto, ni siquiera en 2013 cuando se escribió era correcto. Como offtopic me parece FLIPANTE la ligereza con la que algunos hacen tutoriales de Android, escribiendo código que ni siquiera funciona en el 90% de los dispositivos, y enseñando MAL a la gente. Si te fijas la mayoría de los comentarios son "tu código no funciona".
Cualquier versión de Android superior a Gingerbread dará un NetworkOnMainThreadException, lo mejor, como ya te he dicho en el anterior post, es usar librerías para HTTP, ya que te hacen casi todo el trabajo. Para empezar no usar las librerías de Apache, que llevan deprecated casi desde que salieron. Tienes varias, como Volley, OkHttp o Retrofit. |
|
#6
|
||||
|
||||
|
Bueno si, para ser casi nuevo en el mundo android jeje, algo aun se me pasa, si he visto que hoy en dia utilizan httpURLConnection para comunicarse y que es lo que funciona y Volley tambien, pero claro, ya que es mucho pedir que me arreglaseis ese trozo de código implementando el volley o el http, seguiré buscando ejemplos y estudiando un poquitin mas jiji, aunque nose el tiempo q llevo probando cosas y si no son errores de codigo, es porque me responde todo error jajajaja, en fin.... de todos modos, os doy las GRACIAS a los 2 por haberme conestado y ayudado, muy amables y repito GRACIAS
|
|
#7
|
||||
|
||||
|
Jejejeje he estado mirando cositas por ahi y en fin, he echo unos cambios y así queda mi codigo ahora, pero el problema ahora es que al pulsar un boton del alertbox, se me cierra la aplicacion, ya nose que hacer.... pego el código:
Cita:
Última edición por tukymix Día 21/08/16 a las 14:07:17 |
|
#8
|
||||
|
||||
|
Amén de otros aspectos, tienes un error de concepto importante con el tema de las cosas asíncronas.
No puedes usar la respuesta hasta que la biblioteca, Volley en este caso, la haya obtenido y te la comunique. Este listener no vale para nada según está: public void onResponse(String response) { resp = response; } En el listener lo que tienes que poner es el código que quieras que se ejecute cuando tengas la respuesta (o una llamada a otro método donde lo hagas). Si intentas usar "resp" inmediatamente te dará una NullPointerException porque a Volley ni le ha dado tiempo a bajarse la página. En el momento que hagas queue.add(stringRequest) tu método debería terminar. Todo el código que tengas después para procesar la respuesta tiene que ejecutarse a raíz del onResponse, porque si lo ejecutas seguido la respuesta todavía no existe ya que Volley sigue trabajando en segundo plano y no tendrá el resultado hasta que te avise. |
|
#9
|
||||
|
||||
|
Solucionado !!! Jejejje, he echo lo que me dijisteis, muchisimas gracias, de verdad, que gusto es tener ayuda de la buena
|
| Respuesta |
Estás aquí
|
||||||
|
||||||
«
Tema Anterior
|
Siguiente tema
»
|
|
Hora actual: 17:37:22 (GMT +1)
HTCMania: líderes desde el 2007


. La mayoría de estas librerías (Volley lo hace) ofrecen ya listeners para las respuestas HTTP, tanto para las positivas (2XX) como para las negativas (cualquier otra respuesta o fallo en la conexión, en este último caso un 0)



