|
||
|
|
|
|||||||
| 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 |
![]() |
|
|
Herramientas |
|
#1
|
||||
|
||||
|
Problema con Threads
Muy buenas un día mas,
Ando un poco pez con el java ya que yo soy de base de datos y estoy acostumbrado al plsql codigo lineal y no se ejecuta un paso sin terminar el otro, mi problema los hilos.... Estoy haciendo pruebas con la api de google images, en resumen tengo una clase que implenta una llamada con resultado un json donde me esta devolviendo todas las url de imagenes a buscar, por lo que he leido y para conseguir que funcione debía meterlo en un nuevo thread y así lo he hecho, Ahora quiero jugar con esas url y para hacer una prueba quiero imprimirla en un textView pero con el tema de los hilos no pinta naaaaada y si esta devolviendome urls.... ![]() ![]() Algún experto? [PHP]public class probar extends SherlockActivity { private TextView texto1; private ApiGImages googleimg = new ApiGImages(null); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.probar); texto1 = (TextView) findViewById(R.id.textView1); Thread thread = new Thread(new Runnable() { public void run() { googleimg.BuscarImagenes("panchito"); try { texto1.setText(googleimg.getJArray().getJSONObject (0) .getString("unescapedUrl")); } catch (Exception e) { } } }); thread.start(); } } [/PHP] PD: siento hacer preguntas tan tontas que seguro no tienen nada de dificultad pero me tiene parado to la tarde... yo si quereis una query os la monto jejej
__________________
Prueba mis aplicaciones para android:
Signature Maker - Código en GitHub Pain Log - Código en GitHub Square attack |
|
|
|
#2
|
||||
|
||||
|
Los cambios en las views deben hacerse en el hilo principal.
Prueba poniendo a continuación del setText lo siguiente: texto1.post(new Runnable() { public void run() { texto1.invalidate(); } }); |
| Gracias de parte de: | ||
|
#3
|
||||
|
||||
|
Funciona perfectamente!!!!
Pero puedes explicarme que hace porq ahora si??? Voy a tener q buscar información sobre los hilos.... entiendo entoces que todos los eventos on deben hacerse siempre en el hilo principal pero me has dejado un poco perdido con el invalidate ejejje gracias una vez más
__________________
Prueba mis aplicaciones para android:
Signature Maker - Código en GitHub Pain Log - Código en GitHub Square attack |
|
#4
|
||||
|
||||
|
El invalidate le dice a la Activity que debe volver a pintar el control que estás invalidando, y al volver a pintarse ya te la pinta con el texto nuevo.
En tu caso necesitas hacerlo porque el setText lo has hecho fuera del hilo principal, y por tanto aunque has cambiado el texto no le ha dicho al hilo principal que debe volver a pintarlo. Y ahí es donde entra el "post", lo que hace es decirle al control que cuando vuelva a estar disponible en el hilo principal ejecute el contenido del "Runnable" en dicho hilo. |
| Gracias de parte de: | ||
|
#5
|
||||
|
||||
|
EDIT: No había visto el mensaje de antes
![]() El invalidate es para que Android repinte el componente en cuestión. Con los TextView lo hace cuando quiere... vamos, que el setText cambia el texto internamente pero como ya estaba pintado a veces no lo refresca. En vez del post new Runnable que comenta kriogeN es más rápido (cómodo) llamar simplemente a texto1.postInvalidate(), que es lo mismo y está pensado para estos casos.
__________________
El mejor Cuatro en Raya de Android (Hilo en HTCMania, Play Store) ¡Un millón de descargas!
|
| Gracias de parte de: | ||
|
#6
|
||||
|
||||
|
EDIT: No había visto el mensaje de antes
![]() El invalidate es para que Android repinte el componente en cuestión. Con los TextView lo hace cuando quiere... vamos, que el setText cambia el texto internamente pero como ya estaba pintado a veces no lo refresca. En vez del post new Runnable que comenta kriogeN es más rápido (cómodo) llamar simplemente a texto1.postInvalidate(), que es lo mismo y está pensado para estos casos. ![]() Lo que ocurre es que normalmente no tengo que usarlos, solamente con algunas ImageView un poco puñeteras después de bajar imágenes desde Internet, pero yo lo hago todo con AsyncTask y en el 99% de los casos los "set" a Views que hago en el "onPostExecute" funcionan bien. |
|
#7
|
||||
|
||||
|
de lujo,,,, pues siguiente prueba usar las url que me devuelve descargar las imagenes y meterlas a los imageview
gracias !!!!
__________________
Prueba mis aplicaciones para android:
Signature Maker - Código en GitHub Pain Log - Código en GitHub Square attack |
|
#8
|
||||
|
||||
|
Los invalidate en mis apps se han convertido en parte del ritual de magia negra (acompañan al Project - Clean cuando el R se vuelve loco o a las configuraciones extrañas del proguard para funcionar con admob).
A mí realmente creo que no me ha pasado nunca, empecé a meterlos porque a muchos usuarios les pasaban cosas raras de textos que no cambiaban, puntuaciones que seguían igual, etc. Eso lo solucionó (y el setText lo hacía incluso desde el hilo principal). La teoría dice que si cambias algo debería auto invalidarse... así que es un suceso paranormal
__________________
El mejor Cuatro en Raya de Android (Hilo en HTCMania, Play Store) ¡Un millón de descargas!
|
|
#9
|
||||
|
||||
|
Buenas,,, sigo teniendo problemas con el pintado.... hace lo q quiere
Me descarga la imagen, pero no la redibuja sin embargo es apagar la pantalla encender y ahi está [PHP]imagen = (ImageView) findViewById(R.id.IMG); Thread thread = new Thread(new Runnable() { @Override public void run() { try { DescargaImagen .download( "http://www.trompospeonza.eoldal.hu/img/original/3/peonza-5.gif", imagen); imagen.postInvalidate(); } catch (Exception e) { e.printStackTrace(); } } }); thread.start();[/PHP]
__________________
Prueba mis aplicaciones para android:
Signature Maker - Código en GitHub Pain Log - Código en GitHub Square attack |
|
#10
|
||||
|
||||
|
¿El DescargaImagen.download bloquea el hilo hasta que recibe la imagen o no? Por si acaso el postInvalidate se ejecuta antes de que se haya descargado (en cuyo caso no valdría para nada).
__________________
El mejor Cuatro en Raya de Android (Hilo en HTCMania, Play Store) ¡Un millón de descargas!
|
|
#11
|
||||
|
||||
|
Ademas me estoy creando un hilo cuando creo q no haría falta ya que tengo esto un AsyncTask Tengo una clase que contiene un Asyntask que me descarga la imagen y me guarda el bitmap (resultado) en una variable privada, ademas tengo este metodo que llama al asyntask. [PHP] public void download(String URL, ImageView imageView) { GetXMLTask task = new GetXMLTask(); task.execute(URL); //en el post execute del task me devuelve un Bitmap resultado a la clase //Entiendo que hay que parar aqui hasta que el Asyntask acabe... imageView.setImageBitmap(resultado); } } [/PHP] ¿como lo bloqueo? gracias de nuevo
__________________
Prueba mis aplicaciones para android:
Signature Maker - Código en GitHub Pain Log - Código en GitHub Square attack Última edición por Dild0 Día 15/04/13 a las 10:16:59. |
|
#12
|
||||
|
||||
|
No tienes que bloquear nada, simplemente llama al postInvalidate después de poner la imagen nueva en el código de descarga (después del setImageBitmap)
__________________
El mejor Cuatro en Raya de Android (Hilo en HTCMania, Play Store) ¡Un millón de descargas!
|
|
#13
|
||||
|
||||
|
Te pongo todo el codigo. [PHP] ImageView a; private DescargarImagenes PPP = new DescargarImagenes(); public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.probar); a = (ImageView) findViewById(R.id.IMG); PPP.DownloadImage("http://www.trompospeonza.eoldal.hu/img/original/3/peonza-5.gif",a); } } [/PHP] [PHP] public class DescargarImagenes { private Bitmap resultado; public DescargarImagenes() { super(); } public void DownloadImage(String URL, ImageView imageView) { GetXMLTask task = new GetXMLTask(); task.execute(URL); imageView.setImageBitmap(resultado); imageView.postInvalidate(); } private class GetXMLTask extends AsyncTask<String, Void, Bitmap> { @Override protected Bitmap doInBackground(String... urls) { Bitmap map = null; for (String url : urls) { map = downloadImage(url); } return map; } // Sets the Bitmap returned by doInBackground @Override protected void onPostExecute(Bitmap result) { resultado = result; } // Creates Bitmap from InputStream and returns it private Bitmap downloadImage(String url) { Bitmap bitmap = null; InputStream stream = null; BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inSampleSize = 1; try { stream = getHttpConnection(url); bitmap = BitmapFactory.decodeStream(stream, null, bmOptions); stream.close(); } catch (IOException e1) { e1.printStackTrace(); } return bitmap; } // Makes HttpURLConnection and returns InputStream private InputStream getHttpConnection(String urlString) throws IOException { InputStream stream = null; URL url = new URL(urlString); URLConnection connection = url.openConnection(); try { HttpURLConnection httpConnection = (HttpURLConnection) connection; httpConnection.setRequestMethod("GET"); httpConnection.connect(); if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { stream = httpConnection.getInputStream(); } } catch (Exception ex) { ex.printStackTrace(); } return stream; } } } [/PHP]
__________________
Prueba mis aplicaciones para android:
Signature Maker - Código en GitHub Pain Log - Código en GitHub Square attack |
|
#14
|
||||
|
||||
|
Estás poniendo una imagen nula en el ImageView porque lo haces justo después de lanzar el Execute del GetXMLTask.
Lo que tienes que hacer en enviar el ImageView al GetXMLTask (en el constructor del GetXMLTask lo puedes hacer). Y en el onPostExecute hacer esto: imageView.setImageBitmap(result); imageView.postInvalidate(); |
|
#15
|
||||
|
||||
|
Estás poniendo una imagen nula en el ImageView porque lo haces justo después de lanzar el Execute del GetXMLTask.
Lo que tienes que hacer en enviar el ImageView al GetXMLTask (en el constructor del GetXMLTask lo puedes hacer). Y en el onPostExecute hacer esto: imageView.setImageBitmap(result); imageView.postInvalidate(); ![]() ![]() ![]() ![]() ![]()
__________________
Prueba mis aplicaciones para android:
Signature Maker - Código en GitHub Pain Log - Código en GitHub Square attack Última edición por Dild0 Día 15/04/13 a las 11:50:34. |
|
#16
|
||||
|
||||
|
Hola, me surge una duda viendo el comportamiento que estoy teniendo....
En el layout tengo el gridview que carga imagenes y un boton que abre una nueva activity, Al pulsar el botón para abrirse la nueva activiad no carga o es muy lento ya que tengo hilos por otro lado ejecutandose tanto asyntask dentro de clases y trheads, como puedo cancelar todos esos hilos que haya por detras???? sl2
__________________
Prueba mis aplicaciones para android:
Signature Maker - Código en GitHub Pain Log - Código en GitHub Square attack |
|
#17
|
||||
|
||||
|
Hola, me surge una duda viendo el comportamiento que estoy teniendo....
En el layout tengo el gridview que carga imagenes y un boton que abre una nueva activity, Al pulsar el botón para abrirse la nueva activiad no carga o es muy lento ya que tengo hilos por otro lado ejecutandose tanto asyntask dentro de clases y trheads, como puedo cancelar todos esos hilos que haya por detras???? sl2 ![]() Parece ser que los asyntask se ejecutan en un único hilo hasta la version 3.0 que permiten elegir cargarlos en un pool de hilos (con este comando THREAD_POOL_EXECUTOR), quiere decir que hasta q un asyntask no finaliza no se llama al doInBackground del siguiente (si al onPreExecute). Mi segundo activity llamaba a un asyntask que se quedaba en cola de ahi la tardanza. Para solucionarlo guarde todos mis task en una coleccion y en el onStop los fui cancelando quedando el task de mi nueva activity el primero de la cola y ya ir todo como la seda. http://developer.android.com/intl/es...AsyncTask.html Si he dicho algo incorrecto que me corrijan los expertos. Sl2 y gracias....
__________________
Prueba mis aplicaciones para android:
Signature Maker - Código en GitHub Pain Log - Código en GitHub Square attack |
|
#18
|
||||
|
||||
|
¡Gracias por la info! Me parece un cambio muy radical por parte del API de Android, pero efectivamente es tal como indicas y puede dar muchos quebraderos de cabeza no saberlo.
__________________
El mejor Cuatro en Raya de Android (Hilo en HTCMania, Play Store) ¡Un millón de descargas!
|
![]() |
Estás aquí
|
||||||
|
||||||