<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es">
	<id>https://wiki.cifprodolfoucha.es/index.php?action=history&amp;feed=atom&amp;title=PDM_Avanzado_Threads</id>
	<title>PDM Avanzado Threads - Historial de revisiones</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.cifprodolfoucha.es/index.php?action=history&amp;feed=atom&amp;title=PDM_Avanzado_Threads"/>
	<link rel="alternate" type="text/html" href="https://wiki.cifprodolfoucha.es/index.php?title=PDM_Avanzado_Threads&amp;action=history"/>
	<updated>2026-10-17T06:20:09Z</updated>
	<subtitle>Historial de revisiones de esta página en el wiki</subtitle>
	<generator>MediaWiki 1.34.2</generator>
	<entry>
		<id>https://wiki.cifprodolfoucha.es/index.php?title=PDM_Avanzado_Threads&amp;diff=999&amp;oldid=prev</id>
		<title>Wiki: Página creada con «==Introdución==  Máis información en: http://developer.android.com/guide/components/processes-and-threads.html   Os threads vannos permitir ter diferentes fíos de execu...»</title>
		<link rel="alternate" type="text/html" href="https://wiki.cifprodolfoucha.es/index.php?title=PDM_Avanzado_Threads&amp;diff=999&amp;oldid=prev"/>
		<updated>2016-05-26T18:20:13Z</updated>

		<summary type="html">&lt;p&gt;Página creada con «==Introdución==  Máis información en: http://developer.android.com/guide/components/processes-and-threads.html   Os threads vannos permitir ter diferentes fíos de execu...»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Página nueva&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==Introdución==&lt;br /&gt;
&lt;br /&gt;
Máis información en: http://developer.android.com/guide/components/processes-and-threads.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Os threads vannos permitir ter diferentes fíos de execución, separados do fío principal (chamado main) onde se atenden os eventos do usuario na interface.&lt;br /&gt;
&lt;br /&gt;
É moi importante ter dúas consideracións cando estamos a manexar o thread principal:&lt;br /&gt;
&lt;br /&gt;
* Non deixar bloqueado o thread principal, por exemplo, cargando unha imaxe.&lt;br /&gt;
* Non se pode acceder os elementos da interface (botóns,….) dende un fío diferente ao principal.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O primeiro é necesario xa que podemos provocar un ANR (Application Not Responding), no que aparece un dialogbox indicando que a aplicación deixou de funcionar.&lt;br /&gt;
&lt;br /&gt;
[[Imagen:PDM_Avanzada_Threads_1.jpg | 400px | center]]&lt;br /&gt;
&lt;br /&gt;
Imaxinemos que queremos cargar unha imaxe dende Internet. Isto pode levar moito tempo, e a aplicación non pode esperar a cargar a imaxe.&lt;br /&gt;
&lt;br /&gt;
Para isto, creamos un novo fío de execución.&lt;br /&gt;
&lt;br /&gt;
Temos varias formas de facelo,con AsyncTask e con Threads. &lt;br /&gt;
&lt;br /&gt;
==Threads==&lt;br /&gt;
&lt;br /&gt;
Cando creamos un obxecto da clase Thread podemos sobrescribir o método run ou crealo mandando no construtor un obxecto de interface runable que implemente o método run.&lt;br /&gt;
&lt;br /&gt;
Por exemplo:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; line enclose=&amp;quot;div&amp;quot; highlight=&amp;quot;7&amp;quot; &amp;gt;&lt;br /&gt;
private void crearThread(){&lt;br /&gt;
        Thread fio = new Thread(){&lt;br /&gt;
        	&lt;br /&gt;
        	public void run(){&lt;br /&gt;
        		for (int a=0;a&amp;lt;10;a++){&lt;br /&gt;
        			try {&lt;br /&gt;
					Thread.sleep(1000);&lt;br /&gt;
        			Log.i(&amp;quot;THREAD&amp;quot;,String.valueOf(a));&lt;br /&gt;
				} catch (InterruptedException e) {&lt;br /&gt;
					// TODO Auto-generated catch block&lt;br /&gt;
					e.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
        			}&lt;br /&gt;
        		} 	// FIN DO RUN&lt;br /&gt;
        	       };&lt;br /&gt;
	        fio.start();&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Nota:&amp;lt;/u&amp;gt; A liña 7 indica que o Thread &amp;#039;durma&amp;#039; durante 1 segundo (1000 mseg).&lt;br /&gt;
&lt;br /&gt;
A outra forma sería:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; line enclose=&amp;quot;div&amp;quot; highlight=&amp;quot;&amp;quot; &amp;gt;&lt;br /&gt;
private void crearThreadRunable(){&lt;br /&gt;
        Thread fio = new Thread(new Runnable() {&lt;br /&gt;
			&lt;br /&gt;
			public void run() {&lt;br /&gt;
				// TODO Auto-generated method stub&lt;br /&gt;
	    		for (int a=0;a&amp;lt;10;a++){&lt;br /&gt;
        			try {&lt;br /&gt;
					Thread.sleep(1000);&lt;br /&gt;
	        			Log.i(&amp;quot;THREAD&amp;quot;,String.valueOf(a));&lt;br /&gt;
				} catch (InterruptedException e) {&lt;br /&gt;
					// TODO Auto-generated catch block&lt;br /&gt;
					e.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
        		}	// Fin do for			&lt;br /&gt;
			} //Fin do run()&lt;br /&gt;
		   } //Fin do runnable&lt;br /&gt;
        ); // Fin no new Thread&lt;br /&gt;
        &lt;br /&gt;
        fio.start();&lt;br /&gt;
    }	// FIN DO METODO&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Nestes dous exemplos estamos &amp;#039;parando&amp;#039; a execución do Thread un segundo (sleep(1000)) e imprimindo no log a valor do contador a.&lt;br /&gt;
&lt;br /&gt;
Agora supoñamos que queremos modificar un texto (TextView) cos datos do contador (variable a).&lt;br /&gt;
&lt;br /&gt;
Para iso temos que ter unha referencia da caixa de texto dentro do fío e &amp;#039;&amp;#039;&amp;#039;iso non é posible&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
O seguinte código da un erro xa que non podemos referenciar á caixa de texto dentro de fío.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; line enclose=&amp;quot;div&amp;quot; highlight=&amp;quot;&amp;quot; &amp;gt;&lt;br /&gt;
	private void crearThread(){&lt;br /&gt;
	       final TextView texto = (TextView)findViewById(R.id.txtContador);&lt;br /&gt;
 	       Thread fio = new Thread(){&lt;br /&gt;
        	&lt;br /&gt;
        	public void run(){&lt;br /&gt;
        		for (int a=0;a&amp;lt;10;a++){&lt;br /&gt;
      			try {&lt;br /&gt;
					Thread.sleep(1000);&lt;br /&gt;
	        			texto.setText(String.valueOf(a));&lt;br /&gt;
				} catch (InterruptedException e) {&lt;br /&gt;
					// TODO Auto-generated catch block&lt;br /&gt;
					e.printStackTrace();&lt;br /&gt;
				}&lt;br /&gt;
        		}&lt;br /&gt;
        	}&lt;br /&gt;
               };&lt;br /&gt;
               fio.start();&lt;br /&gt;
&lt;br /&gt;
	}	// FIN DO crearThread&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Para solucionalo, temos a opción de usar un [http://developer.android.com/reference/android/os/Handler.html Handler], que vén a ser coma unha ponte entre un fío e o fío principal.&lt;br /&gt;
&lt;br /&gt;
==Paso de mensaxes==&lt;br /&gt;
&lt;br /&gt;
Máis información en: http://developer.android.com/reference/android/os/Handler.html&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Nota:&amp;lt;/u&amp;gt; A clase Handler pertence ao paquete &amp;#039;&amp;#039;&amp;#039;android.os&amp;#039;&amp;#039;&amp;#039;, cando importedes a clase escoller &amp;#039;&amp;#039;&amp;#039;android.os.Handler&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Como indicamos antes non podemos referenciar ningún elemento da interface dentro dun fío.&lt;br /&gt;
&lt;br /&gt;
Nos casos en que isto sexa necesario teremos que utilizar un &amp;#039;&amp;#039;&amp;#039;AsyncTask&amp;#039;&amp;#039;&amp;#039; ou un &amp;#039;&amp;#039;&amp;#039;Thread con paso de mensaxes&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Un &amp;#039;&amp;#039;&amp;#039;Handler&amp;#039;&amp;#039;&amp;#039; é unha ponte para pasar información dende o Thread a un procedemento no que podemos acceder ao fío principal.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; line enclose=&amp;quot;div&amp;quot; highlight=&amp;quot;&amp;quot; &amp;gt;&lt;br /&gt;
	private Handler ponte = new Handler(){&lt;br /&gt;
	    @Override&lt;br /&gt;
	    public void handleMessage(Message msg) {&lt;br /&gt;
			&lt;br /&gt;
		}&lt;br /&gt;
	&lt;br /&gt;
	}; // Fin do Handler &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
O parámetro &amp;#039;&amp;#039;&amp;#039;msg&amp;#039;&amp;#039;&amp;#039; vai recibir información dende o fío, e dende o Handler si imos poder referenciar os elementos gráficos da UI.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; line enclose=&amp;quot;div&amp;quot; highlight=&amp;quot;&amp;quot; &amp;gt;&lt;br /&gt;
	private Handler ponte = new Handler(){&lt;br /&gt;
	    @Override&lt;br /&gt;
	    public void handleMessage(Message msg) {&lt;br /&gt;
	    	TextView texto = (TextView)findViewById(R.id.txtContador);&lt;br /&gt;
	    	texto.setText(String.valueOf(msg.arg1));&lt;br /&gt;
		}&lt;br /&gt;
	}; // Fin do Handler&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; line enclose=&amp;quot;div&amp;quot; highlight=&amp;quot;9-11&amp;quot; &amp;gt;&lt;br /&gt;
private void crearThread(){&lt;br /&gt;
		&lt;br /&gt;
        Thread fio = new Thread(){&lt;br /&gt;
        	&lt;br /&gt;
        	public void run(){&lt;br /&gt;
        		for (int a=0;a&amp;lt;10;a++){&lt;br /&gt;
        			try {&lt;br /&gt;
					Thread.sleep(1000);&lt;br /&gt;
	        			Message msg = new Message();&lt;br /&gt;
	        			msg.arg1=a;&lt;br /&gt;
        			        ponte.sendMessage(msg);&lt;br /&gt;
				} catch (InterruptedException e) {&lt;br /&gt;
					// TODO Auto-generated catch block&lt;br /&gt;
					e.printStackTrace();&lt;br /&gt;
				} // fin do catch&lt;br /&gt;
        		} // Fin do for&lt;br /&gt;
        	} // Fin do run&lt;br /&gt;
        }; // fin do new Thread&lt;br /&gt;
        fio.start();&lt;br /&gt;
&lt;br /&gt;
}	// Fin do crearThread &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fixarse como o msg pódese utilizar para enviar datos de moi diversas formas:&lt;br /&gt;
* msg.setData(data): sendo data un obxecto da clase Bundle (almacena  pares da datos cos métodos setTIPODATO e recupera con getTIPODATO). &lt;br /&gt;
* msg.obj: un Object&lt;br /&gt;
* msg.arg1: un enteiro&lt;br /&gt;
* msg.arg2: outro enteiro.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ata o de aquí non hai problema ou si....se o deixades así podedes ver coma vos da un aviso na clase Handle:&lt;br /&gt;
&lt;br /&gt;
[[Imagen:PDM_Avanzada_Threads_2.jpg | 300px | center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Para solucionar o problema temos que ter unha referencia débil da Activity na que queremos acceder ós elementos gráficos.&lt;br /&gt;
&lt;br /&gt;
Debido a que o Handler manexa unha cola de mensaxes, é recomendable que sexa definido como Static, xa que dita cola é compartida por todos os obxectos handler que teñamos, é o procesar dita mensaxe non pode ser destruída polo proceso de garbagecollection se o handler non está definido como de clase.&lt;br /&gt;
&lt;br /&gt;
Se cambiamos sen máis a clase a ‘Static’ imos atopar o problema de que cando queiramos referenciar un método ou un obxecto fora da clase Handler (que estea definido na clase Activity), non podemos facelo. &lt;br /&gt;
&lt;br /&gt;
Podedes facer a proba:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; line enclose=&amp;quot;div&amp;quot; highlight=&amp;quot;4,5&amp;quot; &amp;gt;&lt;br /&gt;
	private static Handler ponte = new Handler(){&lt;br /&gt;
	    @Override&lt;br /&gt;
	    public void handleMessage(Message msg) {&lt;br /&gt;
	    	TextView texto = (TextView)findViewById(R.id.txtContador);&lt;br /&gt;
	    	texto.setText(String.valueOf(msg.arg1));&lt;br /&gt;
		}&lt;br /&gt;
	}; // Fin do Handler&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Neste caso sería máis conveniente utilizar a clase Asynctask (a veremos a continuación), pero a modo de curiosidade imos ver como podemos solucionar o problema:&lt;br /&gt;
&lt;br /&gt;
Para solucionalo, temos que facer que exista unha referencia ‘débil’ da Activity principal dentro do Handler. &lt;br /&gt;
&lt;br /&gt;
Para facelo temos que crear un construtor no handler onde lle imos pasar &amp;quot;this&amp;quot; como parámetro e que será a referencia débil:&lt;br /&gt;
&lt;br /&gt;
Cambiamos polo tanto a forma anterior e creamos un obxecto dunha clase Handler definida previamente:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Nota:&amp;lt;/u&amp;gt; A clase activity principal neste exemplo se chama &amp;quot;OutraActividade&amp;quot;. Deberedes cambiala en función do voso nome.&lt;br /&gt;
&lt;br /&gt;
Código a poñer dentro da activity de nome OutraActividade.java&lt;br /&gt;
Pasamos de:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; line enclose=&amp;quot;div&amp;quot; highlight=&amp;quot;&amp;quot; &amp;gt;&lt;br /&gt;
	private Handler ponte = new Handler(){&lt;br /&gt;
	    @Override&lt;br /&gt;
	    public void handleMessage(Message msg) {&lt;br /&gt;
	    	TextView texto = (TextView)findViewById(R.id.txtContador);&lt;br /&gt;
	    	texto.setText(String.valueOf(msg.arg1));&lt;br /&gt;
		}&lt;br /&gt;
	&lt;br /&gt;
	}; // Fin do Handler&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
A&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; line enclose=&amp;quot;div&amp;quot; highlight=&amp;quot;&amp;quot; &amp;gt;&lt;br /&gt;
private static class ClassPonte extends Handler {&lt;br /&gt;
		&lt;br /&gt;
	private WeakReference&amp;lt;OutraActividade&amp;gt; mTarget=null;&lt;br /&gt;
			&lt;br /&gt;
	ClassPonte(OutraActividade target) {&lt;br /&gt;
       		mTarget = new WeakReference&amp;lt;OutraActividade&amp;gt;(target);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	@Override&lt;br /&gt;
	public void handleMessage(Message msg) {&lt;br /&gt;
			&lt;br /&gt;
		OutraActividade target = mTarget.get();&lt;br /&gt;
		    	&lt;br /&gt;
	    	TextView texto1 = (TextView)target.findViewById(R.id.txtContador);&lt;br /&gt;
    		texto1.setText(String.valueOf(msg.arg1));&lt;br /&gt;
    	}&lt;br /&gt;
}; // Fin do Handler&lt;br /&gt;
&lt;br /&gt;
private ClassPonte ponte = new ClassPonte(this);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Fixarse coma dentro da clase ClassPonte, no método handleMessage podemos facer referencia a método non static grazas o obxecto target:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; line enclose=&amp;quot;div&amp;quot; highlight=&amp;quot;&amp;quot; &amp;gt;&lt;br /&gt;
OutraActividade target = mTarget.get();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Caso práctico==&lt;br /&gt;
&lt;br /&gt;
O obxectivo desta práctica e ver como funciona un Thread e como podemos usar un Handler para pasar mensaxes dende o fío a activity e poder acceder os elementos gráficos da mesma.&lt;br /&gt;
&lt;br /&gt;
Consta dun botón cun TextView onde se vai a amosar un contador. Cando se preme sobre o botón o contador empeza a funcionar.&lt;br /&gt;
&lt;br /&gt;
[[Imagen:PDM_Avanzada_Threads_3.jpg | 400px | center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Creamos a activity===&lt;br /&gt;
&lt;br /&gt;
*Nome do proxecto: &amp;#039;&amp;#039;&amp;#039;UD7_01_Threads&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
*Nome da activity: &amp;#039;&amp;#039;&amp;#039;UD7_01_Threads.java&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Código do layout xml&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot; line enclose=&amp;quot;div&amp;quot; highlight=&amp;quot;&amp;quot; &amp;gt;&lt;br /&gt;
&amp;lt;RelativeLayout xmlns:android=&amp;quot;http://schemas.android.com/apk/res/android&amp;quot;&lt;br /&gt;
    xmlns:tools=&amp;quot;http://schemas.android.com/tools&amp;quot;&lt;br /&gt;
    android:layout_width=&amp;quot;match_parent&amp;quot;&lt;br /&gt;
    android:layout_height=&amp;quot;match_parent&amp;quot;&lt;br /&gt;
    tools:context=&amp;quot;${relativePackage}.${activityClass}&amp;quot; &amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;TextView&lt;br /&gt;
        android:id=&amp;quot;@+id/UD7_01_txtContador&amp;quot;&lt;br /&gt;
        android:layout_width=&amp;quot;wrap_content&amp;quot;&lt;br /&gt;
        android:layout_height=&amp;quot;wrap_content&amp;quot;&lt;br /&gt;
        android:layout_centerHorizontal=&amp;quot;true&amp;quot;&lt;br /&gt;
        android:layout_centerVertical=&amp;quot;true&amp;quot;&lt;br /&gt;
        android:text=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;Button&lt;br /&gt;
        android:id=&amp;quot;@+id/UD7_01_btnCrono&amp;quot;&lt;br /&gt;
        android:layout_width=&amp;quot;wrap_content&amp;quot;&lt;br /&gt;
        android:layout_height=&amp;quot;wrap_content&amp;quot;&lt;br /&gt;
        android:layout_alignParentTop=&amp;quot;true&amp;quot;&lt;br /&gt;
        android:layout_centerHorizontal=&amp;quot;true&amp;quot;&lt;br /&gt;
        android:layout_marginTop=&amp;quot;21dp&amp;quot;&lt;br /&gt;
        android:text=&amp;quot;INICIAR CRONO&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/RelativeLayout&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Código da clase UD7_01_Threads&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Obxectivo:&amp;#039;&amp;#039;&amp;#039; Utilizar un Thread con paso de mensaxes mediante Handler.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;NOTA:&amp;lt;/u&amp;gt; Neste exemplo o código da clase Hander e o código da clase Thread están definidos dentro da propia Activity. Nada impide que se definan en clases separadas.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot; line enclose=&amp;quot;div&amp;quot; highlight=&amp;quot;15,18-41,43,46-64,66,73,76-80&amp;quot; &amp;gt;&lt;br /&gt;
import java.lang.ref.WeakReference;&lt;br /&gt;
&lt;br /&gt;
import android.app.Activity;&lt;br /&gt;
import android.os.Bundle;&lt;br /&gt;
import android.os.Handler;&lt;br /&gt;
import android.os.Message;&lt;br /&gt;
import android.view.View;&lt;br /&gt;
import android.view.View.OnClickListener;&lt;br /&gt;
import android.widget.Button;&lt;br /&gt;
import android.widget.TextView;&lt;br /&gt;
import android.widget.Toast;&lt;br /&gt;
&lt;br /&gt;
public class UD7_01_Threads extends Activity {&lt;br /&gt;
&lt;br /&gt;
	private final int TEMPO_CRONO=10;&lt;br /&gt;
	&lt;br /&gt;
	// INICO DA CLASE HANDLER&lt;br /&gt;
	private static class ClassPonte extends Handler {&lt;br /&gt;
&lt;br /&gt;
		private WeakReference&amp;lt;UD7_01_Threads&amp;gt; mTarget = null;&lt;br /&gt;
&lt;br /&gt;
		ClassPonte(UD7_01_Threads target) {&lt;br /&gt;
			mTarget = new WeakReference&amp;lt;UD7_01_Threads&amp;gt;(target);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		@Override&lt;br /&gt;
		public void handleMessage(Message msg) {&lt;br /&gt;
&lt;br /&gt;
			UD7_01_Threads target = mTarget.get();&lt;br /&gt;
			TextView texto1 = (TextView) target&lt;br /&gt;
					.findViewById(R.id.UD7_01_txtContador);&lt;br /&gt;
&lt;br /&gt;
			if (msg.arg2==1){&lt;br /&gt;
				Toast.makeText(target.getApplicationContext(), &amp;quot;ACABOUSE O CRONO&amp;quot;, Toast.LENGTH_LONG).show();&lt;br /&gt;
				texto1.setText(String.valueOf(0));&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				texto1.setText(String.valueOf(msg.arg1));&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}; // Fin do Handler&lt;br /&gt;
&lt;br /&gt;
	private ClassPonte ponte = new ClassPonte(this);&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	private class MeuFio extends Thread{&lt;br /&gt;
		&lt;br /&gt;
	 	public void run(){&lt;br /&gt;
    		for (int a=0;a&amp;lt;=TEMPO_CRONO;a++){&lt;br /&gt;
    			try {&lt;br /&gt;
					Thread.sleep(1000);&lt;br /&gt;
					Message msg = new Message();&lt;br /&gt;
					msg.arg1=a;&lt;br /&gt;
	    			ponte.sendMessage(msg);&lt;br /&gt;
    			} catch (InterruptedException e) {&lt;br /&gt;
				// TODO Auto-generated catch block&lt;br /&gt;
    				e.printStackTrace();&lt;br /&gt;
    			}&lt;br /&gt;
    		}&lt;br /&gt;
    		Message msgFin = new Message();&lt;br /&gt;
    		msgFin.arg2=1;&lt;br /&gt;
			ponte.sendMessage(msgFin);&lt;br /&gt;
	 	} 	// FIN DO RUN&lt;br /&gt;
	};&lt;br /&gt;
	 &lt;br /&gt;
	private Thread meuFio;&lt;br /&gt;
	&lt;br /&gt;
	private void xestionarEventos(){&lt;br /&gt;
		Button btnCrono = (Button)findViewById(R.id.UD7_01_btnCrono);&lt;br /&gt;
		btnCrono.setOnClickListener(new OnClickListener() {&lt;br /&gt;
			&lt;br /&gt;
			@Override&lt;br /&gt;
			public void onClick(View v) {&lt;br /&gt;
				// TODO Auto-generated method stub&lt;br /&gt;
				&lt;br /&gt;
				if ((meuFio==null) || (!meuFio.isAlive())){&lt;br /&gt;
					Toast.makeText(getApplicationContext(), &amp;quot;INICIANDO FIO&amp;quot;, Toast.LENGTH_LONG).show();&lt;br /&gt;
					meuFio = new MeuFio();&lt;br /&gt;
					meuFio.start();&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
					Toast.makeText(getApplicationContext(), &amp;quot;NON TE DEIXO INICIAR O FIO ATA QUE REMATE :)&amp;quot;, Toast.LENGTH_LONG).show();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
    @Override&lt;br /&gt;
    protected void onCreate(Bundle savedInstanceState) {&lt;br /&gt;
        super.onCreate(savedInstanceState);&lt;br /&gt;
        setContentView(R.activity_ud7_01__threads);&lt;br /&gt;
        &lt;br /&gt;
        xestionarEventos();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
* Liña 15: Definimos o tempo do crono. Cando chegue a ese valor para.&lt;br /&gt;
* Liñas 18-41: Definimos a clase Handler que vai capturar as mensaxes enviadas dende o Thread.&lt;br /&gt;
:* Liñas 33-36: Utilizamos a propiedade arg2 do Message para saber cando acaba o contador (chega ao valor indicado na liña 15). Dende o Thread imos enviar un valor igual a 1 para indicalo.&lt;br /&gt;
:* Liña 38: Asinamos o valor enviado na propiedade arg1 do Message ao EditText da activity principal.&lt;br /&gt;
&lt;br /&gt;
* Liña 43: Definimos o obxecto da clase Handler que vai utilizar o Thread.&lt;br /&gt;
* Liñas 46-64: Definimos a clase Thread que vai utilizar a activity principal para o contador.&lt;br /&gt;
:* Liña 53: Dentro do bucle enviamos en Message na propiedade arg1 o valor do contador.&lt;br /&gt;
:* Liñas 60-62: Cando sae do bucle enviamos na propiedade arg2 o valor 1 para indicar á ponte que xa rematou o fío.&lt;br /&gt;
&lt;br /&gt;
* Liña 66: Definimos o obxecto da clase Thread.&lt;br /&gt;
* Liña 73: Xestionamos o evento Click do botón.&lt;br /&gt;
:* Liñas 76-80: En caso de que o fío non se iniciara nunca ou se xa rematou, instanciamos un novo fío.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; -- [[Usuario:angelfg|Ángel D. Fernández González]] e [[Usuario:Carrion|Carlos Carrión Álvarez]] -- (2014).&lt;/div&gt;</summary>
		<author><name>Wiki</name></author>
		
	</entry>
</feed>