Ver mensagens sem resposta | Ver tópicos ativos Hoje é 20 Nov 2019, 05:51



Responder Tópico  [ 1 Mensagem ] 
 [Mini Tuto] Sincronizando ciclos de vida de uma work thread 
Autor Mensagem
Google employee
Google employee

Data de registro: 17 Jul 2011, 11:55
Mensagens: 2657
Localização: São Paulo
Mensagem [Mini Tuto] Sincronizando ciclos de vida de uma work thread
Olá pessoal, acabo de publicar esse mini-tuto no meu Blog.

Sincronizando ciclos de vida de uma work thread e da activity

Muitas vezes temos a necessidade de executar uma tarefa em segundo plano de uma forma contínua, ficando em loop enquanto uma activity esteja sendo executada. Mas, com uma característica adicional: desejamos sincronizar o ciclo de vida da tarefa com o ciclo de vida da activity.
Para isso vamos definir uma classe MyTask que implementa a interface Runnable, e usar dois loops aninhados para controlar o ciclo de vida da tarefa. No loop externo, vamos usar a característica blocante da queue com bloqueio para aguardar/liberar a execução do serviço no loop interno.
Implementamos os seguintes métodos do ciclo de vida da tarefa:
-resume() - para (re)iniciar a tarefa;
-pause() - para encerrar o loop interno;
-stop() - para encerrar a tarefa;
E os métodos auxiliares para setar/checar o status da tarefa: setStatus() e isRunning().
O método doSomething() representa o serviço a ser executado pela tarefa, no caso, apenas incrementamos um contador e usamos o handler para atualizar a tela.

Na activity, implementamos os seguintes métodos:
-onCreate - instanciamos o textView e o button, e colocamos código para pausar/reiniciar a contagem da tarefa;
-onStart - instanciamos a tarefa, a thread e startamos a thread;
-onResume - chamamos o método resume da tarefa;
-onPause - chamamos o método pause da tarefa;
-onStop - chamamos o método stop da tarefa e esperamos a finalização da thread.

Notem que o objetivo é manter a tarefa ativa somente quando a activity estiver no status "resumed".

Seguem os códigos:

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

    <TextView  
    android:id="@+id/tv1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:text="@string/hello"
    />


    <Button android:text="Change Status"
     android:id="@+id/changeStatus"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content">

     </Button>

</LinearLayout>

 


TesteThread5Activity.class

package br.agorandroid.testethread5;

import android.app.Activity;
import android.os.Bundle;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.atomic.AtomicInteger;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

/**
 * @author A H Gusukuma
 *
 *         agorandroid.blogspot.com.br
 */

    public class TesteThread5Activity extends Activity {
        private volatile Thread mThread;
        private volatile MyTask mTask = null;
        public enum Status {CREATED, RUNNING, PAUSED, FINISHED}
        private BlockingQueue<String> mQueue = new SynchronousQueue<String>();
        AtomicInteger mCount = new AtomicInteger();
        Handler mHandler = new Handler();
       
        TextView tv;
        Button bt;
       
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            Log.i("msg", "Activity created");
           
            tv = (TextView) findViewById(R.id.tv1);
           
            bt = (Button) findViewById(R.id.changeStatus);
           
            bt.setOnClickListener(new  OnClickListener() {
                public void onClick(View v) {
                if (mTask != null) {
                    Log.i("msg", "Button onClick");
                    if (mTask.isRunning()) {
                        mTask.pause();
                    } else {
                        mTask.resume();
                    }
                }
                }
            });
        }

        @Override
        protected void onStart() {
            super.onStart();
            Log.i("msg", "Activity started");
            mTask = new MyTask();
            mThread = new Thread(mTask);
            mThread.start();
        }
       
        @Override
        protected void onResume() {
            super.onResume();
            Log.i("msg", "Activity resumed");
            mTask.resume();
        }
       
        @Override
        protected void onPause() {
            mTask.pause();         
            super.onPause();
            Log.i("msg", "Activity paused");
        }
       
        @Override
        protected void onStop() {
            mTask.stop();
            while (true) {
                  try {
                      mThread.join();
                      break;
                  } catch (InterruptedException e) {
                      // ignore
                  }
            }
            super.onStop();
            Log.i("msg", "Activity stopped");
        }
       
        @Override
        protected void onDestroy() {
            Log.i("msg", "Activity destroyed");
            super.onDestroy();
        }

        /**
         * @author A H Gusukuma      agorandroid.blogspot.com.br
         *
         * MyTask
         *
         */

        private class MyTask implements Runnable {

            private Status mStatus;
           
            public MyTask() {
                this.mStatus = Status.CREATED;
            }
           
            @Override
            public void run() {
               
                while (true) {
                    try {
                        if (mQueue.take().equals("stop")) {
                            break;
                        }
                        setStatus(Status.RUNNING);
                        while (isRunning()) {
                            doSomething();
                        }
                        Log.i("msg", "Task paused");
                    } catch (InterruptedException e) {
                        // ignore
                    }
                }
               
                setStatus(Status.FINISHED);
                Log.i("msg", "Task stopped");
                mTask = null;
            }
           
            private synchronized void setStatus(Status status) {
                this.mStatus = status;
            }
            
            private synchronized boolean isRunning() {
                return mStatus == Status.RUNNING;
            }
                        
            public void resume() {
                Log.i("msg", "Task resumed ");
                try {
                    mQueue.put("start");
                } catch (InterruptedException e) {
                    // ignore
                }
            }
            
            public void pause() {
                Log.i("msg", "Task pause requested ");
                setStatus(Status.PAUSED);
            }
            
            public void stop() {
                Log.i("msg", "Task stop requested ");
                try {
                    mQueue.put("stop");
                } catch (InterruptedException e) {
                    // ignore
                }
            }
            
            private void doSomething() {
                mCount.incrementAndGet();
               
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        tv.setText(""+mCount.get());
                    }
                });
               
                Log.i("msg", "Task count = " + mCount.get());
               
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // ignore
                }
            }
        }       
    }

   
 


O código está cheio de Log´s para podermos acompanhar a execução dos métodos.

Vejam um teste que executei:


07-14 14:45:19.614: I/msg(362): Activity created
07-14 14:45:19.646: I/msg(362): Activity started
07-14 14:45:19.646: I/msg(362): Activity resumed
07-14 14:45:19.646: I/msg(362): Task resumed
07-14 14:45:19.684: I/msg(362): Task count = 1
07-14 14:45:20.716: I/msg(362): Task count = 2
07-14 14:45:21.736: I/msg(362): Task count = 3
07-14 14:45:22.748: I/msg(362): Task count = 4
07-14 14:45:23.814: I/msg(362): Task count = 5
07-14 14:45:24.822: I/msg(362): Task count = 6
07-14 14:45:25.824: I/msg(362): Task count = 7
07-14 14:45:25.834: I/msg(362): Button onClick
07-14 14:45:25.834: I/msg(362): Task pause requested
07-14 14:45:26.845: I/msg(362): Task paused
07-14 14:45:27.584: I/msg(362): Button onClick
07-14 14:45:27.584: I/msg(362): Task resumed
07-14 14:45:27.584: I/msg(362): Task count = 8
07-14 14:45:28.603: I/msg(362): Task count = 9
07-14 14:45:29.610: I/msg(362): Task count = 10
07-14 14:45:30.671: I/msg(362): Task count = 11
07-14 14:45:31.732: I/msg(362): Task count = 12
07-14 14:45:32.751: I/msg(362): Task count = 13
07-14 14:45:32.966: I/msg(362): Task pause requested
07-14 14:45:32.973: I/msg(362): Activity paused
07-14 14:45:33.163: I/msg(362): Task stop requested
07-14 14:45:33.780: I/msg(362): Task paused
07-14 14:45:33.780: I/msg(362): Task stopped
07-14 14:45:33.780: I/msg(362): Activity stopped
07-14 14:45:33.780: I/msg(362): Activity destroyed

 


Espero que gostem,

Abraços

_________________
Abraços
___________
Novo App: CalcMat - Calculadora de materiais para concreto
Blog: Agorandroid - sobre programação Android
Twitter: @Agorandroid
___________
Campanha: Facilite sua vida e a dos outros usuários
Cuide do ciclo de vida do seu tópico:
no onCreate(): seja claro, se necessário poste o código e as mensagens de erro.
no onClick(): responda às sugestões.
no onStop(): evite "ninguém?", "alguém?", etc. Procure acrescentar alguma nova informação.
no onDestroy(): resolvido o assunto, poste imediatamente a solução, e, coloque no título do primeiro post [Resolvido].


14 Jul 2013, 16:17
Perfil
Mostrar mensagens anteriores:  Organizar por  
Responder Tópico   [ 1 Mensagem ] 

Quem está online

Usuários vendo este fórum: (_FM_), aechiara, alex, alexcost2002, am2net, andrelom, antoniodourado, arilsonm, ariostorecco, arquivo51, Arthas, azero, beeshop, bigr ecreio, BMaia, BOMBER27, breko, brian15, brunogh, Brunohc, Carlos Alexandre, Carmizini, celiapinheiro, cesao, cezaraf, cfranca, comolatti, Corneta, craudiao, Danilo Dias, dannieltec, Delão, digiwise, dmd, edsonel, Eduardo, Eneias, erosvaldo, euguns, everaldo, fabiano_eletro, fabrizior, Felipe, Felipe Ferreira, felipecomp19, felipetesc, fernandofsf, ferrodecaju, Filipe larizzatti, furlanrapha, Gabriel Teófilo, Geovanne Duarte, germanno, guiba_picolino, Guilherme Cobain, guilhermesmo, GuilhermeZampieri, guitarro17, gustavobarbosa, gutodias, HAMSES, hebert, Henrique Ferraz, ICCrawler - ICjobs, Idelto, jeanbr07, Jenius, jijo, jlucasps, juliana_costa, juliancesar, juliherms, jzaires, lalaine, Lelinho, Leonardo, mapis, marciosoliveira, Marini, marlovich, Mayara Trevisol, Mayron Cimardi, MBetioli, mcroft, mendes_lu, Michel, mirelli, neimarguerra, NeruLL, onaiggac, Padawan, Paulo, Paulo Bizzo, paulosantos, PicsearchDroid, R2-D2, rafael.cioban, rafael.winter, ramonsa, Renan, renatocoliveira, rfrafael, ricardzanella, rlecheta, robsonrg, Rodrigo, rodrigo_mg, romualdo, sergio, Shaman286, skcratch, sobrinho, srmoreira, tchou, teamamus, thiago20, thiagotomais, Tiago Sousa Roch, tiagoxv, tonholis, unnamedd, Vania, vilmartr, viniciusluiz, washington, Wds, WiseNut, woyzeck, YaCy e 1 visitante


Você não pode criar novos tópicos neste fórum
Você não pode responder tópicos neste fórum
Você não pode editar suas mensagens neste fórum
Você não pode excluir suas mensagens neste fórum
Você não pode enviar anexos neste fórum

Procurar por:
cron

© 2007 - 2016 Portal Android - Comunidade de Desenvolvedores Android

Estamos no Linkedin    Siga-nos no twitter


Powered by phpBB - Hospedado por Bemobi