Lo que quiero hacer:

Quiero usar un subproceso de trabajo para actualizar regularmente un campo de texto en el subproceso de interfaz de usuario. Digamos, cada 2 segundos durante 30 segundos. Necesito la cuenta regresiva de 30 segundos incluso si la aplicación no está en primer plano. Por ahora, estoy evaluando los méritos de dos enfoques diferentes (ambos usando hilos de trabajo) en la implementación de esto. No publicaré el código completo aquí para simplificar las cosas y también porque no estoy pidiendo encontrar ningún problema en mi código. Ambas soluciones funcionan bien.

Solución n. ° 1: use Thread.sleep() dentro de un bucle for

for (int i = 30; i > 0; i-=2) {
    Message msg = mHandler.obtainMessage(MSG_ID, i, 0);
    msg.sendToTarget();

    try {
        Thread.sleep(2000);
    } catch(Throwable t) {
        // catch error
    }

}

Solución n. ° 2: utilice CountDownTimer

Looper.prepare()

new CountDownTimer(30000, 2000) {
    public void onTick(long millUntilFinish) {
        int seconds = (int)(millUntilFinish);
        Message msg = mHandler.obtainMessage(MSG_ID, seconds, 0);
        msg.sendToTarget();
    }

    public void onFinish() {
        // left blank for now
    }
}.start();

Looper.loop();

Mi pregunta

Mientras ambos funcionan, quiero saber si hay una forma "mejor" o "preferida" de hacerlo por cualquier razón. Creo que puede haber áreas particularmente en la duración de la batería, pero también en el rendimiento, la precisión o el diseño del código, donde una solución es mejor que la otra.

Lo que he hecho hasta ahora para responder esta pregunta

Mi propia evaluación hasta ahora de leer esta pregunta SO y CountDownTimer 's documentación es que, dado que ambos se ejecutan en el subproceso de trabajo, ambos no tienen Posibilidad de ANR. Ambas soluciones también garantizarán que una "actualización" ocurrirá solo después de que la actualización anterior haya finalizado. Desafortunadamente, esto es todo lo que tengo y espero que alguien pueda ayudarme o guiarme a una pregunta SO perspicaz y / o similar que haya pasado por alto o no haya podido encontrar.

Escribo esta pregunta con un poco de precaución, ya que no tengo un código problemático que requiera depuración, pero creo que se encuentra dentro de SO's categoría de un "problema de programación específico", que no ha sido respondido y no está incluido en la lista de respuestas fuera del tema.

2
user7646649 6 mar. 2017 a las 16:17

2 respuestas

La mejor respuesta

1.Calling Thread.sleep pausa la ejecución del hilo durante un tiempo en el que el temporizador de cuenta regresiva realmente usa devoluciones de llamada para notificar eventos de vencimiento del temporizador y es de naturaleza asíncrona.

2. Si la ejecución del subproceso se detiene, no podrá usar ese subproceso específico para ninguna otra operación hasta que se agote el tiempo de espera, por lo tanto, no se recomienda usar el enfoque Thread.sleep. Obviamente, hay una carga en la CPU si tiene que reanudar la ejecución del hilo y pausarla. Donde, como en el caso del temporizador de cuenta regresiva, el hilo continúa en estado de ejecución / inactivo y como cuando ocurren eventos, se dispara a los respectivos oyentes.

1
siva 6 mar. 2017 a las 13:42
call Thread.sleep() method is not good idea beacuse ii sleep the UI Thread and disadvantage of  CountDownTimer is, It Will stop when ur screen is off hence instead of this two try  Handler for that like this


 Handler handler;
    Runnable runnable;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        handler = new Handler();
        Runnable runnable = new Runnable() {
            @Override
            public void run()
            {
                if (dataReceived)
                {
                    cancelHandler();
                }
            }
        };
        handler.postDelayed(runnable, 100);
    }

    public void cancelHandler()
    {
        handler.removeCallbacks(runnable);
    }
0
Rishi 6 mar. 2017 a las 13:36