|
||
|
![]() |
![]() |
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
|
||||
|
||||
Duda delay en bucle
Buenas he empezado hace poco con android, estoy intentando hacer un pequeño album de fotos apartir de un array. Lo que quiero es mostrar a partir de un ImageView una imagen del array cada 5 segundos pero no logro conseguirlo, he intentado utilizar el SystemClock.sleep() pero no me funciona, supongo que lo hago de una forma erronea, dejo mi codigo para que alguien pueda modificarlo y ayudarme. Gracias
import android.content.res.TypedArray; import android.media.Image; import android.os.SystemClock; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.ImageView; import java.util.logging.Handler; public class MainActivity extends AppCompatActivity { private ImageView img; private TypedArray fotos; private int numFoto = 0; private Thread temporizador; @override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); img = (ImageView) findViewById(R.id.imagen); cargarArray(); albumFotos(); } public void cargarArray() { fotos = getResources().obtainTypedArray(R.array.fotos); } public void albumFotos() { while(numFoto < 4){ numFoto++; img.setImageDrawable(fotos.getDrawable(numFoto)); SystemClock.sleep(5000); } } } |
|
#2
|
||||
|
||||
La espera tienes que hacerla en segundo plano, de lo contrario el método no terminará y no se ejecutará el método onDraw que pinta en la pantalla.
Es decir, hasta que no termina el código de esperar 5 segundos x 4 fotos = 20 segundos no pintará la imagen, que por supuesto será sólo la última foto. Tu método "albumFotos" debería ser un AsyncTask, que en su doInBackground haga el bucle y la espera, y en su oProgressUpdate establezca la imagen. Algo así: [PHP] protected void doInBackground() { while(numFoto < 4){ numFoto++; publishProgress(numFoto) SystemClock.sleep(5000); } } protected void onProgressUpdate(Integer... progress) { img.setImageDrawable(fotos.getDrawable(progress[0])); } [/PHP] |
Gracias de parte de: | ||
#3
|
||||
|
||||
El ejemplo que te ha dado kriogeN es justo cómo harías lo que estás haciendo (bucle con espera) sin bloquear el sistema.
Para este caso particular que solo quieres ejecutar una cosa cuando pase cierto tiempo hay más mecanismos, como el postDelayed que tiene cualquier View o mejor todavía un Handler que te da más control. Le pasas un Runnable con lo que quieras que haga y el tiempo en el que quieres que lo ejecute. Es más ligero que un AsyncTask, te ahorras crear un hilo de ejecución y tenerlo bloqueado con sleep y sabes que siempre estás ejecutando el código en el hilo principal.
__________________
El mejor Cuatro en Raya de Android (Hilo en HTCMania, Play Store) ¡Un millón de descargas!
|
Gracias de parte de: | ||
#4
|
||||
|
||||
Gracias por contestar! aun así me sigue costando mucho entender en que casos utilizarse cada tipo de hilo, también leí por ahí que se pueden hacer/modificar los servicios en ve de hilos, no se si entendí bien, es cierto?
Última edición por joselugf Día 03/11/16 a las 11:24:32. |
#5
|
||||
|
||||
A grandes rasgos solo hay dos tipos de hilos, el hilo principal y todos los demás.
Cuando escribes un programa se va ejecutando una línea detrás de otra, eso es un hilo, una secuencia de órdenes. Hasta que no acaba la orden anterior no se pone con la siguiente. En Android existe un hilo llamado hilo principal que es el que se encarga de ver si el usuario ha tocado la pantalla, dónde, avisar a la app para que responda y llamar a tus métodos onXXX cuando corresponda, pintar la pantalla con los cambios y volver a ver si el usuario hizo algo. Todo esto unas 60 veces por segundo para que el sistema sea fluido. Como un juego... También se le llama UI Thread precisamente porque es el que gestiona la interfaz de usuario. El resto de hilos los creas cuando necesitas ejecutar una secuencia de código que dura mucho tiempo y dejaría bloqueado a Android que no podría hacer su trabajo en el hilo principal (por ejemplo un sleep, una conexión a un servidor, procesar una imagen, etc.). Si quieres más información hay mucho material en las redes. Aquí mismamente: http://www.sgoliver.net/blog/tareas-...d-y-asynctask
__________________
El mejor Cuatro en Raya de Android (Hilo en HTCMania, Play Store) ¡Un millón de descargas!
|
Gracias de parte de: | ||
#6
|
||||
|
||||
Finalmente lo he conseguido con la solucion que me dieron. Lo he hecho así
public class MainActivity extends AppCompatActivity { private ImageView img; private TypedArray fotos; private int numFoto = 0; @override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); img = (ImageView) findViewById(R.id.imagen); cargarArray(); pasaFotos(); } public void cargarArray() { fotos = getResources().obtainTypedArray(R.array.fotos); } public void pasaFotos(){ FotosAleatorias fotosAle = new FotosAleatorias(); fotosAle.execute(); } private class FotosAleatorias extends AsyncTask<Void, Integer, Void> { @override protected Void doInBackground(Void... params) { while (numFoto < 4) { publishProgress(numFoto); numFoto++; SystemClock.sleep(5000); } return null; } @override protected void onProgressUpdate(Integer... values) { img.setImageDrawable(fotos.getDrawable(values[0])); } } } Aunque no se si es la forma "correcta" ya que he hecho la clase que extiende de AsincTask dentro del main y no se si sería mas conveniente en hacerlo en una clase nueva aparte??. Última edición por joselugf Día 03/11/16 a las 14:00:04. |
#7
|
||||
|
||||
AsyncTask fotosAle = new AsyncTask<Void, Integer, Void>() { /* el doInBackground y el onProgressUpdate igual */ }; fotosAle.execute();
__________________
El mejor Cuatro en Raya de Android (Hilo en HTCMania, Play Store) ¡Un millón de descargas!
|
Gracias de parte de: | ||