<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>fr4gus &#187; Java</title>
	<atom:link href="http://www.fr4gus.com/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.fr4gus.com</link>
	<description>Just another WordPress site</description>
	<lastBuildDate>Fri, 23 Dec 2011 16:04:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Manejando cambio de orientación con un Progress Dialog</title>
		<link>http://www.fr4gus.com/2011/10/05/manejando-cambio-de-orientacion-con-un-progress-dialog/</link>
		<comments>http://www.fr4gus.com/2011/10/05/manejando-cambio-de-orientacion-con-un-progress-dialog/#comments</comments>
		<pubDate>Wed, 05 Oct 2011 04:20:11 +0000</pubDate>
		<dc:creator>Franklin García</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Activity]]></category>
		<category><![CDATA[Change]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Orientation]]></category>
		<category><![CDATA[ProgressDialog]]></category>

		<guid isPermaLink="false">http://www.fr4gus.com/?p=538</guid>
		<description><![CDATA[Puede que tengamos una pantalla, que en algún momento ejecute un cambio o solicitud de manera asíncrona. Para esto debemos mostrarle al usuario algo mientras, ya sea de manera determinada (progreso del trabajo o tarea) o indeterminada (el famoso spinner). Cuando hay un cambio de orientación, si la actividad no maneja el cambio de orientación, [...]]]></description>
			<content:encoded><![CDATA[<p>Puede que tengamos una pantalla, que en algún momento ejecute un cambio o solicitud de manera asíncrona. Para esto debemos mostrarle al usuario algo mientras, ya sea de manera determinada (progreso del trabajo o tarea) o indeterminada (el famoso <em>spinner</em>).</p>
<p>Cuando hay un cambio de orientación, si la actividad no maneja el cambio de orientación, probablemente sea destruida y recreada. Entonces ¿Qué pasa con el <em>ProgressDialog</em>?.</p>
<p>Iniciemos con dos reglas que debemos seguir:</p>
<ol>
<li>Si va a crear el <em>AsyncTask</em> dentro de la actividad como un inner class, asegúrese de que sea estática. Las inner class no estáticas, guardan una referencia de la outer class, en nuestro caso, la Actividad. Esto quiere decir que estamos &#8220;filtrando&#8221; (<em>leaking</em>) memoria, pues esa referencia de la actividad queda ahi mientras siga vivo el <em>AsyncTask</em>, y esto hay que evitarlo.</li>
<li>Para crear el <em>ProgressDialog</em>, utilice los métodos que tiene disponible la actividad. Me refiero a <em>onCreateDialog</em>, <em>showDialog</em> y <em>dismissDialog</em>. Esto por que a la hora de cambiar la orientación de la pantalla y al destruir y recrear la actividad, Android va a mantener el estado de los dialogs que estaban presentes y se encargará de mostrarlos nuevamente cuando la actividad es recreada.</li>
</ol>
<div>Ahora bien, aún siguiendo estas reglas, el principal problema es que la actividad que creó el <em>AsyncTask</em> puede que se destruya por lo que el <em>AsyncTask</em> pierda la referencia (y así debe ser). La solución es simplemente desacoplar la actividad del <em>AsyncTask</em>. Empleando los métodos del ciclo de vida de la activad, es posible &#8220;notificar&#8221; o &#8220;actualizar&#8221; el <em>AsyncTask</em>, para que se percate del cambio de actividad y pueda mostrar o ocultar el <em>ProgressDialog</em>.</div>
<p>El consenso es utilizar el método <em>onRetainNonConfigurationInstance</em>, para &#8220;guardar&#8221; la referencia del <em>AsynctTask</em>, así, cuando la nueva actividad es creada, ella se dará cuenta si la tarea todavia está en progreso, para poder &#8220;acoplarse&#8221; a ella.</p>
<div>
<pre class="brush: java; title: ; notranslate">
public class EjemploProgressDialogActivity extends Activity {
    public static final String TAG = &quot;EXAMPLE_DIALOG&quot;;

    public static final int PROGRESS_DIALOG = 1;

    MyTask task;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Log.d(TAG, &quot;onCreate&quot;);
        Object obj = getLastNonConfigurationInstance();
        if (obj != null &amp;&amp; obj instanceof MyTask) {
            Log.d(TAG, &quot;Tarea previa ejecutandose&quot;);
            task = (MyTask) obj;
            task.attach(this);
        } else {
            task = new MyTask(this);
            task.execute(10);
            Log.d(TAG, &quot;Nueva tarea creada y ejecutada&quot;);
        }
    }

    @Override
    protected Dialog onCreateDialog(int id) {

        switch (id) {
        case PROGRESS_DIALOG:
            ProgressDialog pd = new ProgressDialog(this);
            pd.setTitle(&quot;Trabajando&quot;);
            pd.setMessage(&quot;Por favor espere...&quot;);
            return pd;

        default:
            break;
        }
        return super.onCreateDialog(id);
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, &quot;onPause&quot;);
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d(TAG, &quot;onRestart&quot;);

    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, &quot;onResume&quot;);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, &quot;onStart&quot;);
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, &quot;onStop&quot;);
    }

    @Override
    public Object onRetainNonConfigurationInstance() {
        // Aqui es donde se hace la magia
        if (task != null) {
            task.deattach();
            return task;
        }
        return super.onRetainNonConfigurationInstance();
    }

    private static class MyTask extends AsyncTask {
        WeakReference ctx;

        public MyTask(Activity activity) {
            super();
            attach(activity);
        }

        @Override
        protected void onPreExecute() {
            Activity activity = ctx.get();
            if (activity != null &amp;&amp; !activity.isFinishing()) {
                Log.d(TAG, &quot;Mostrando Progress Dialog&quot;);
                activity.showDialog(PROGRESS_DIALOG);
            }
        }

        @Override
        protected Void doInBackground(Integer... params) {
            int seconds = params[0];
            try {
                Log.d(TAG, &quot;Tarea va a durar &quot; + seconds + &quot; segundos&quot;);
                Thread.sleep(seconds * 1000);
                Log.d(TAG, &quot;Tarea Lista&quot;);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            if (ctx != null &amp;&amp; ctx.get() != null) {
                Activity activity = ctx.get();
                if (!activity.isFinishing()) {
                    Log.d(TAG, &quot;Ocultando Progress Dialog&quot;);
                    activity.dismissDialog(PROGRESS_DIALOG);
                }
            }
        }

        public void attach(Activity activity) {
            this.ctx = new WeakReference(activity);
        }

        public void deattach() {
            ctx = null;
        }

    }
}
</pre>
</div>
<p>En la línea 14, pueden ver que en el método <em>onCreate</em> se pregunta si se salvó algún objeto previamente y luego se hacen los chequeos respectivos para asegurarse que el objeto sea el <em>AsyncTask</em>. En este ejemplo en particular, se crea el AsyncTask en el método <em>onCreate</em>, por lo que en el caso de que no exista, se crea.</p>
<p>En la línea 18 se ejecuta el método attach,para que el <em>AsyncTask</em> tenga la nueva referencia de la Actividad.</p>
<p>En la línea 77 que es el momento en que la actividad da su último suspiro, el <em>AsyncTask</em> se desacopla y se &#8220;salva&#8221; la referencia al <em>AsyncTask</em> para que la siguiente actividad (si es el caso) la retome, como vimos en el método onCreate.</p>
<p>Si ven la implementación del AsyncTask, primero que todo, se guarda la referencia a la actividad dentro de un WeakReference, para así evitar &#8220;filtrar&#8221; memoria.</p>
<p>En los métodos <em>onPreExecute</em> y <em>onPostExecute</em> se hacen validaciones para asegurarse de que la referencia de la actividad sea válidad (que exista la referencia y que la actividad no esté en proceso de morirse).</p>
<p>Si ejecutáramos éste código,  sin mover el dispositivo, esta sería la salida en la bitácora:</p>
<pre>10-04 21:54:46.254: DEBUG/EXAMPLE_DIALOG(6155): onCreate
10-04 21:54:46.294: DEBUG/EXAMPLE_DIALOG(6155): Mostrando Progress Dialog
10-04 21:54:46.514: DEBUG/EXAMPLE_DIALOG(6155): Tarea va a durar 10 segundos
10-04 21:54:46.514: DEBUG/EXAMPLE_DIALOG(6155): Nueva tarea creada y ejecutada
10-04 21:54:46.514: DEBUG/EXAMPLE_DIALOG(6155): onStart
10-04 21:54:46.524: DEBUG/EXAMPLE_DIALOG(6155): onResume
10-04 21:54:56.518: DEBUG/EXAMPLE_DIALOG(6155): Tarea Lista
10-04 21:54:56.524: DEBUG/EXAMPLE_DIALOG(6155): Ocultando Progress Dialog
10-04 21:55:12.395: DEBUG/EXAMPLE_DIALOG(6155): onPause
10-04 21:55:12.554: DEBUG/EXAMPLE_DIALOG(6155): onStop</pre>
<p>Pero si cambiamos la orientación del dispositivo, esto sería el resultado:</p>
<pre>te
10-04 21:56:08.584: DEBUG/EXAMPLE_DIALOG(6155): Mostrando Progress Dialog
10-04 21:56:08.754: DEBUG/EXAMPLE_DIALOG(6155): Nueva tarea creada y ejecutada
10-04 21:56:08.754: DEBUG/EXAMPLE_DIALOG(6155): onStart
10-04 21:56:08.754: DEBUG/EXAMPLE_DIALOG(6155): Tarea va a durar 10 segundos
10-04 21:56:08.764: DEBUG/EXAMPLE_DIALOG(6155): onResume
10-04 21:56:10.424: DEBUG/EXAMPLE_DIALOG(6155): onPause
10-04 21:56:10.424: DEBUG/EXAMPLE_DIALOG(6155): onStop
10-04 21:56:10.544: DEBUG/EXAMPLE_DIALOG(6155): onCreate
10-04 21:56:10.544: DEBUG/EXAMPLE_DIALOG(6155): Tarea previa ejecutandose
10-04 21:56:10.544: DEBUG/EXAMPLE_DIALOG(6155): onStart
10-04 21:56:10.704: DEBUG/EXAMPLE_DIALOG(6155): onResume
10-04 21:56:18.755: DEBUG/EXAMPLE_DIALOG(6155): Tarea Lista
10-04 21:56:18.755: DEBUG/EXAMPLE_DIALOG(6155): Ocultando Progress Dialog
10-04 21:56:21.626: DEBUG/EXAMPLE_DIALOG(6155): onPause
10-04 21:56:21.784: DEBUG/EXAMPLE_DIALOG(6155): onStop</pre>
<p>Imprimí además cuando se ejecutan otros métodos del ciclo de vida, para tener una referencia de cuando ocurre qué.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fr4gus.com/2011/10/05/manejando-cambio-de-orientacion-con-un-progress-dialog/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Softkeyboard aparece al entrar en una ventana</title>
		<link>http://www.fr4gus.com/2011/07/28/softkeyboard-aparece-al-entrar-en-una-ventana/</link>
		<comments>http://www.fr4gus.com/2011/07/28/softkeyboard-aparece-al-entrar-en-una-ventana/#comments</comments>
		<pubDate>Thu, 28 Jul 2011 17:56:26 +0000</pubDate>
		<dc:creator>Franklin García</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Activity]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[HTC]]></category>
		<category><![CDATA[HTC Desire]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[LG]]></category>
		<category><![CDATA[SoftKeyboard]]></category>

		<guid isPermaLink="false">http://www.fr4gus.com/?p=508</guid>
		<description><![CDATA[Me encontré un &#8220;error&#8221; o &#8220;bug&#8221; muy particular en Android. Lo pongo entre comillas porque aún no tengo confirmación de que así lo sea. El &#8220;bug&#8221; es que ciertos layouts, pueden provocar que el teclado virtual (o softkeyboard) se active tan pronto como la actividad (o ventana) toma foco (se coloca en la pila de [...]]]></description>
			<content:encoded><![CDATA[<p>Me encontré un &#8220;error&#8221; o &#8220;bug&#8221; muy particular en Android. Lo pongo entre comillas porque aún no tengo confirmación de que así lo sea.</p>
<p>El &#8220;bug&#8221; es que ciertos layouts, pueden provocar que el teclado virtual (o softkeyboard) se active tan pronto como la actividad (o ventana) toma foco (se coloca en la pila de ventananas). Según mis pruebas, (que pueden ver en el post) todo pasa cuando el layout tiene un widget contenedor, llámese un ListView, GridView, Gallery, etc. y <strong>debajo de él</strong> un campo de texto. Esta combinación, parece provocar, en <strong>ciertos devices</strong> como el <strong>HTC Desire </strong> y el <strong>LG GX2</strong>, ambos con Android 2.2, la activación del softkeyboad.</p>
<p>El mes pasado puse una pregunta en el grupo de google para Desarrolladores de Android (<a href="http://groups.google.com/group/android-developers/browse_thread/thread/b6671252f89eaf07/9162b31c9716cec9#9162b31c9716cec9" target="_blank">ver pregunta aquí</a>), pero lo único que me contestaron fue como &#8220;mitigarlo&#8221;.</p>
<p>Dentro de las recomendaciones que me hicieron, fue que creara un repositorio con el código, para que otras personas pudieran probarlo. Pueden bajar el código en Github:</p>
<p><a href="https://github.com/fr4gus/AndroidSoftKeyboardBug" target="_blank">https://github.com/fr4gus/AndroidSoftKeyboardBug</a></p>
<p>Me gustaría saber si alguien más lo puede replicar, con cual o cuales devices y si tiene alguna idea de si es un bug o no.</p>
<p>-f4</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fr4gus.com/2011/07/28/softkeyboard-aparece-al-entrar-en-una-ventana/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Usando efectívamente el AsyncTask Parte 2</title>
		<link>http://www.fr4gus.com/2011/05/24/usando-efectivamente-el-asynctask-parte-2/</link>
		<comments>http://www.fr4gus.com/2011/05/24/usando-efectivamente-el-asynctask-parte-2/#comments</comments>
		<pubDate>Tue, 24 May 2011 06:00:04 +0000</pubDate>
		<dc:creator>Franklin García</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[AsyncTask]]></category>
		<category><![CDATA[Best Practice]]></category>
		<category><![CDATA[cancel]]></category>
		<category><![CDATA[doInBackground]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[onCancel]]></category>
		<category><![CDATA[technologia]]></category>
		<category><![CDATA[Tip]]></category>

		<guid isPermaLink="false">http://blog.fr4gus.com/?p=439</guid>
		<description><![CDATA[Ver parte 1 aqui. El otro tip del que les quería hablar con los AsyncTask es más que todo recalcar la importancia de implementar expícitamente la lógica dentro del método doInBackground que permita cancelar el AsyncTask. Si recuerdan de la parte uno, el AsyncTask guarda una referencia &#8220;debil&#8221; de la actividad que lo ejecuta. Además, [...]]]></description>
			<content:encoded><![CDATA[<p>Ver parte 1 <a href="http://blog.fr4gus.com/2011/05/13/usando-efectivamente-el-asynctask-parte-1/">aqui</a>.</p>
<p>El otro tip del que les quería hablar con los AsyncTask es más que todo recalcar la importancia de implementar expícitamente la lógica dentro del método doInBackground que permita cancelar el AsyncTask.</p>
<p>Si recuerdan de la parte uno, el AsyncTask guarda una referencia &#8220;debil&#8221; de la actividad que lo ejecuta. Además, verifica que la Actividad este siendo ejecutada con normalidad, es decir, que la actividad no esté siendo terminada.</p>
<p>Con el código de la parte uno, si el usuario se sale de dicha actividad, vamos a tener el hilo de la actividad corriendo hasta que termine con lo que estaba haciendo. Esto puede  representar un problema ya que tenemos un AsyncTask ejecutandose sin necesidad. Esto es un gasto tanto en procesamiento, memoria, como en la posibilidad de ejecutar otras AsyncTask (recordemos que existe un límite).</p>
<p>La solución a esto es, si la actividad no ha terminado y ya no la ocupamos más, podamos llamar el método calcel(boolean). Esto provocará que el método isCancelled regrese &#8220;true&#8221;, además, para asegurar que onCancelled() sea llamado en vez de onPostExecute(Object), es importante checkear isCancelled dentro de doInBackground, asegurando que la tarea termine lo más pronto posible.</p>
<p>Por ejemplo:</p>
<pre class="brush: java; title: ; notranslate">
public class MyActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Inicialización de la actividad, layout, etc
        MyLongTask task = new MyLongTask(this);
        task.execute(&quot;http://blog.fr4gus.com/api/test.json&quot;);
    }

    @Override
    protected void onPause() {
        // Persistamos cualquier cosa que ocupemos
    }

    static class MyLongTask extends AsyncTask&lt;String, Void, Void&gt; {
        WeakReference&lt;MyActivity&gt; context;

        public MyLongTask(MyActivity activity) {
            context = new WeakReference&lt;MyActivity&gt;(activity);
        }

        @Override
        protected void onPreExecute() {
            // Avísele al usuario que estamos trabajando
        }

        @Override
        protected Void doInBackground(String... params) {
            while(! isCancelled() ){
            // Aquí hacemos una tarea laaarga
            // Y ademas chequeamos que la tarea no ha sido cancelada

            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            MyActivity activity = context.get();
            if (activity != null &amp;&amp; !activity.isFinishing()) {
                // Aquí actualizamos la UI con el resultado
            }
        }
    }

}
</pre>
<p>Los AsyncTask son una herramienta muy util, pero también nos pueden perjudicar si no sabemos utilizarlas correctamente. Pueden provocar leaks de memoria, o uso de recursos innecesariamente. El hecho de que para Android Honeycomb hayan regresado al esquema original con un solo hilo, indica que la idea es que hayan pocos hilos actualizando la interface. De todas maneras hay que aprovechar otras herramientas similares como el método runOnUiThread o los Handlers. La idea es minimizar los riesgos y aprovechar los recursos al máximo.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fr4gus.com/2011/05/24/usando-efectivamente-el-asynctask-parte-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Usando efectívamente el AsyncTask Parte 1</title>
		<link>http://www.fr4gus.com/2011/05/13/usando-efectivamente-el-asynctask-parte-1/</link>
		<comments>http://www.fr4gus.com/2011/05/13/usando-efectivamente-el-asynctask-parte-1/#comments</comments>
		<pubDate>Fri, 13 May 2011 04:24:38 +0000</pubDate>
		<dc:creator>Franklin García</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[AsyncTask]]></category>
		<category><![CDATA[Desarrollo de Software]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[inner class]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[memory leak]]></category>
		<category><![CDATA[static class]]></category>

		<guid isPermaLink="false">http://blog.fr4gus.com/?p=416</guid>
		<description><![CDATA[Imaginemos por ejemplo la aplicación de Twitter, que al iniciar su ejecución, hace un llamado a un método del API de Twitter, que está hospedado en un servidor en Internet. Éste llamado tomará su tiempo, dependiendo del tipo de conexión del usuario. Mientras se obtienen los tweets más recientes, no queremos que la aplicación se [...]]]></description>
			<content:encoded><![CDATA[<p>Imaginemos por ejemplo la aplicación de Twitter, que al iniciar su ejecución, hace un llamado a un método del API de Twitter, que está hospedado en un servidor en Internet. Éste llamado tomará su tiempo, dependiendo del tipo de conexión del usuario. Mientras se obtienen los tweets más recientes, no queremos que la aplicación se congele, provocando un ANR (Application Not Responding) y un eventual Force Close de la aplicación. Por ello Android provee al desarrollador de diferentes herramientas para ejecutar tareas en hilos a parte del hilo principal, entre ellas las clases Handler(desde API Level 1) y AsyncTask (desde API Level 3).</p>
<p>El <a href="http://developer.android.com/reference/android/os/AsyncTask.html">AsyncTask</a> es ampliamente utilizado para ejecutar tareas &#8220;simples&#8221; o &#8220;atómicas&#8221; en un hilo aparte. Su ciclo de ejecución es bastante intuitivo y práctico, comparado con el uso de la clase Handler. En Android 1.5, los AsyncTask eran encolados y un único hilo se encargaba de ejecutarlos uno por uno. A partir de 1.6 hasta Android 2.3.4 (inclusive), los AsyncTask son ejecutados cada uno, por un hilo aparte (sin asegurar su orden). Aqui la clase AsyncTask maneja una cola de ejecución de 10 hilos(dato no confirmado) y una cola de 10 hilos en espera (aunque según Roman Guy <a title="Roman Guy response" href="http://stackoverflow.com/questions/990948/simple-thread-management-java-android" target="_blank">aquí</a>, ese límite ya no existe, aunque no indica en que versión :-/), dándonos aproximádamente 20 AsyncTask &#8220;simultáneos&#8221;. Cuando este límite se excede, se dispara la excepción RejectedExecutionException. Está planeado despues de Honeycomb (Android 3.0), volver a la ejecución sencilla, para evitar los errores de ejecución paralela.</p>
<p>Esta clase es muy útil pero a la vez se convierte, probablemente, en una de las mayores fuentes de memory leaks y application crashes (Force Close) en Android, por parte de desarrolladores que omitan ciertas prácticas a la hora de usar dicha clase. En este primer artículo hablaremos primero sobre los Inner clases y cómo definir una AsycTask adecuadamente.</p>
<h2>1. Inner clases</h2>
<p>Tal vez la razón número uno de leaks en una aplicación Android son las Inner classes dentro de una clase Activity. Las Inner class, tienen una referencia implícita hacia la Outer class. Cuando se crea un AsyncTask, la tendencia es hacerlas dentro de la Actividad donde la ocupamos. Veamos un ejemplo</p>
<pre class="brush: java; title: ; notranslate">
public class MyActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Inicialización de la actividad, layout, etc
        MyLongTask task = new MyLongTask();
        task.execute(&quot;http://blog.fr4gus.com/api/test.json&quot;);
    }

    @Override
    protected void onPause() {
        // Persistamos cualquier cosa que ocupemos
    }

    class MyLongTask extends AsyncTask&lt;String, Void, Void&gt;{

        @Override
        protected void onPreExecute() {
            // Avísele al usuario que estamos trabajando
        }

        @Override
        protected Void doInBackground(String... params) {
            // Aquí hacemos una tarea laaarga
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // Aquí actualizamos la UI con el resultado
        }
    }

}
</pre>
<p>El problema es que éstas inner classes no-estáticas no tienen un ciclo de vida controlado por el desarrollador. La solución está en hacer las classes Inner, estáticas, y pasarle la referencia de la actividad o contexto, pero envolviéndola dentro de un WeakReference. Esto permitirá al Garbage Collector, liberar la memoria del Activity aunque el AsyncTask siga ejecutándose. Es importante que a la hora de usar el WeakReference, se aseguren que la referencia al Activity sea aun válida, verificando que no sea nula y que la activdad no esta terminando.</p>
<pre class="brush: java; title: ; notranslate">
public class MyActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Inicialización de la actividad, layout, etc
        MyLongTask task = new MyLongTask(this);
        task.execute(&quot;http://blog.fr4gus.com/api/test.json&quot;);
    }

    @Override
    protected void onPause() {
        // Persistamos cualquier cosa que ocupemos
    }

    static class MyLongTask extends AsyncTask&lt;String, Void, Void&gt; {
        WeakReference&lt;MyActivity&gt; context;

        public MyLongTask(MyActivity activity) {
            context = new WeakReference&lt;MyActivity&gt;(activity);
        }

        @Override
        protected void onPreExecute() {
            // Avísele al usuario que estamos trabajando
        }

        @Override
        protected Void doInBackground(String... params) {
            // Aquí hacemos una tarea laaarga
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            MyActivity activity = context.get();
            if (activity != null &amp;#038;&amp;#038; !activity.isFinishing()) {
                // Aquí actualizamos la UI con el resultado
            }
        }
    }

}
</pre>
<p><a href="http://blog.fr4gus.com/2011/05/24/usando-efectivamente-el-asynctask-parte-2/">Parte 2</a></p>
<p>Fuentes</p>
<ol>
<li>Documentación de Android sobre memory leaks <a href="http://developer.android.com/resources/articles/avoiding-memory-leaks.html">http://developer.android.com/resources/articles/avoiding-memory-leaks.html</a></li>
<li>Límite de ejecución de los AyncTask: <a href="http://stackoverflow.com/questions/2492909/asynctask-rejectedexecutionexception-and-task-limit">http://stackoverflow.com/questions/2492909/asynctask-rejectedexecutionexception-and-task-limit</a></li>
<li>Implementación de AyncTaskEx de CommonsGuy: <a href="https://github.com/commonsguy/cwac-task">https://github.com/commonsguy/cwac-task</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.fr4gus.com/2011/05/13/usando-efectivamente-el-asynctask-parte-1/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Modificando el widget Gallery de Android</title>
		<link>http://www.fr4gus.com/2011/04/05/modificando-el-widget-gallery-de-android/</link>
		<comments>http://www.fr4gus.com/2011/04/05/modificando-el-widget-gallery-de-android/#comments</comments>
		<pubDate>Tue, 05 Apr 2011 05:46:08 +0000</pubDate>
		<dc:creator>Franklin García</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Gallery]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Widget]]></category>

		<guid isPermaLink="false">http://blog.fr4gus.com/?p=401</guid>
		<description><![CDATA[Saludos internautas, Me tope con un requerimiento donde en una pantalla ocupaba mostrar diferentes items de manera horizontal. La idea es que el usuario pueda pasar entre esos items de manera similar al &#8220;Home&#8221; de Android, esto es, que usted pasa entre escritorios, haciendo &#8220;swap&#8221;. En Android, no existe tal widget que simule este comportamiento. [...]]]></description>
			<content:encoded><![CDATA[<p>Saludos internautas, Me tope con un requerimiento donde en una pantalla ocupaba mostrar diferentes items de manera horizontal. La idea es que el usuario pueda pasar entre esos items de manera similar al &#8220;Home&#8221; de Android, esto es, que usted pasa entre escritorios, haciendo &#8220;swap&#8221;. En Android, no existe tal widget que simule este comportamiento. Ni siquiera tenemos un ListView horizontal (así como lo oye, el ListView es solo vertical). Solamente ofrece algo llamado como ViewFlipper, pero ocupa que usted conozca de antemano la cantidad de items a desplegar (tanto así que por lo general se llena a nivel del archivo XML de layout). Luego vi al Gallery, que en esencia hace lo que ocupo, excepto por un detalle: Al hacer swap (scroll horizontal), si se hace muy &#8220;fuerte&#8221; puede que pasen más de un item. Cuando el item ocupa toda la pantalla (como en el caso del mi proyecto) ver varios items pasar horizontalmente no es una buena experiencia de usuario. <object width="425" height="344" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/hHh-lOnKuO4?hl=en&amp;fs=1" /><param name="allowfullscreen" value="true" /><embed width="425" height="344" type="application/x-shockwave-flash" src="http://www.youtube.com/v/hHh-lOnKuO4?hl=en&amp;fs=1" allowFullScreen="true" allowscriptaccess="always" allowfullscreen="true" /></object>El ViewFlipper fue mi primera opción, pero fue bastante dolorosa, ya que al ocupar conocer de antemano los items a desplegar, cuando se tienen datos dinámicos, tratar de &#8220;compensar&#8221; esto a nivel de código es una pesadilla. En nuestro caso usamos un ViewFlipper con solo 3 items. Al pasar a la derecha o izquierda, era necesario reacomodar todo internamente para que se llenaran los items de los lados de acuerdo a la nueva posición. Esto implica que uno es el que debe controlar los items, la posición, y hasta la animación al pasar de items. Otra gran desventaja, es que a diferencia de un ListView o un GridView, no tiene un adapter (y por eso ocupa saber que items va a contener desde el layout), por lo que se puede llegar a tener problemas de memoria. Al retomar la idea del Gallery, me encontré por ahí este post, que describe una manera para &#8220;modificar&#8221; el comportamiento del Gallery y hacer que sin importar la fuerza con la que se realice el scroll o swap, solo un se moverá al siguiente item. Dicha solución explica que simplemente hay que crear una clase en el proyecto, que herede de Gallery, y que sobreescriba el método onFling devolviendo false.</p>
<pre class="brush: java; title: ; notranslate">
public class MyGallery extends Gallery{

  public MyGallery(Context context, AttributeSet attrs, int defStyle){
    super(context, attrs, defStyle);
  }

  public MyGallery(Context context, AttributeSet attrs){
    super(context, attrs);
  }

  public MyGallery(Context context){
    super(context);
  }

  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
      float velocityY){
    return true;
  }

}</pre>
<p>Para que obtengamos el siguiente comportamiento: <object width="425" height="344" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/HbwodK7lXm0?hl=en&amp;fs=1" /><param name="allowfullscreen" value="true" /><embed width="425" height="344" type="application/x-shockwave-flash" src="http://www.youtube.com/v/HbwodK7lXm0?hl=en&amp;fs=1" allowFullScreen="true" allowscriptaccess="always" allowfullscreen="true" /></object>Fuentes:</p>
<ol>
<li><a href="http://stackoverflow.com/questions/4968426/android-gallery-horrizontal-scroll-rate">http://stackoverflow.com/questions/4968426/android-gallery-horrizontal-scroll-rate</a></li>
<li><a href="http://developer.android.com/reference/android/widget/Gallery.html">http://developer.android.com/reference/android/widget/Gallery.html</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.fr4gus.com/2011/04/05/modificando-el-widget-gallery-de-android/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Como &#8220;meter&#8221; otros componentes dentro de un EditText en Android</title>
		<link>http://www.fr4gus.com/2010/12/02/como-meter-otros-componentes-dentro-de-un-edittext-en-android/</link>
		<comments>http://www.fr4gus.com/2010/12/02/como-meter-otros-componentes-dentro-de-un-edittext-en-android/#comments</comments>
		<pubDate>Thu, 02 Dec 2010 21:35:02 +0000</pubDate>
		<dc:creator>Franklin García</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[EditText]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[merge]]></category>
		<category><![CDATA[trick]]></category>
		<category><![CDATA[truco]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.fr4gus.com/?p=370</guid>
		<description><![CDATA[Normalmente, los campos editables de texto vienen acompañados de otros componentes como botones, imagenes, para ejecutar alguna acción. Pero puede que en algún momento ocupen hacer que su aplicación luzca como esto: La respuesta para la ingcógnita de ¿Cómo se hace? es : imposible usando los componentes nativos de Android . Otra opción es que [...]]]></description>
			<content:encoded><![CDATA[<p>Normalmente, los campos editables de texto vienen acompañados de otros componentes como botones, imagenes, para ejecutar alguna acción. Pero puede que en algún momento ocupen hacer que su aplicación luzca como esto:</p>
<div id="attachment_371" class="wp-caption aligncenter" style="width: 490px"><a href="http://www.fr4gus.com/wp-content/uploads/2010/12/button_inside_EditText.png"><img class="size-full wp-image-371 " title="Botón dentro de un EditText" src="http://www.fr4gus.com/wp-content/uploads/2010/12/button_inside_EditText.png" alt="Botón dentro de un EditText" width="480" height="800" /></a>
<p class="wp-caption-text">Botón dentro de un EditText</p>
</div>
<p>La respuesta para la ingcógnita de <em>¿Cómo se hace?</em> es : <strong><span style="color: #ff0000;">imposible</span></strong> usando los componentes nativos de Android . Otra opción es que usted sea un experimentado desarrollador, con ganas de crear componentes nuevos podría usted crear un componente propio que lo haga.</p>
<p>¿Qué pasa con el resto de los mortales como nosotros? Podemos usar el siguiente &#8220;truco&#8221; (con el que se hizo la imagen anterior):</p>
<p><pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
	android:orientation=&quot;vertical&quot;
	android:layout_width=&quot;fill_parent&quot;
	android:layout_height=&quot;fill_parent&quot;&gt;
	&lt;RelativeLayout
		android:layout_width=&quot;wrap_content&quot;
		android:layout_height=&quot;wrap_content&quot;
		style=&quot;@android:style/Widget.EditText&quot;&gt;
		&lt;EditText
			android:hint=&quot;Type here&quot;
			android:layout_width=&quot;fill_parent&quot;
			android:layout_height=&quot;wrap_content&quot;
			android:layout_toLeftOf=&quot;@+id/SearchButton&quot;
			android:background=&quot;@null&quot;
			android:layout_centerVertical=&quot;true&quot;/&gt;
		&lt;ImageButton
			android:layout_width=&quot;wrap_content&quot;
			android:layout_height=&quot;wrap_content&quot;
			android:layout_alignParentRight=&quot;true&quot;
			android:id=&quot;@+id/SearchButton&quot;
			android:src=&quot;@drawable/ic_menu_search&quot;
			android:background=&quot;@null&quot;/&gt;
	&lt;/RelativeLayout&gt;
&lt;/LinearLayout&gt;
</pre>
</p>
<p>
Básicamente lo que se hace en el XML, es aplicar el estilo de campo editable de texto <span style="color: #0000ff;"><em>@android:style/Widget.EditText</em></span> al layout que contiene a los componentes que queremos agrupar, en este caso un EditText y un ImageButton. Luego hay que &#8220;quitarle&#8221; el fondo al EditText (o ponerle el fondo <span style="color: #0000ff;"><em>@null</em></span>, como gusten llamarlo) para que se vuelta &#8220;transparente&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fr4gus.com/2010/12/02/como-meter-otros-componentes-dentro-de-un-edittext-en-android/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Android-logger</title>
		<link>http://www.fr4gus.com/2010/10/22/android-logger/</link>
		<comments>http://www.fr4gus.com/2010/10/22/android-logger/#comments</comments>
		<pubDate>Fri, 22 Oct 2010 17:12:17 +0000</pubDate>
		<dc:creator>Franklin García</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Desarrollo de Software]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[logcat]]></category>
		<category><![CDATA[logs]]></category>

		<guid isPermaLink="false">http://blog.fr4gus.com/?p=365</guid>
		<description><![CDATA[Me tope por ahi con esta aplicación bastante útil a mi parecer. Simplemente permite leer los logs (los que se obtendría usando la utilidad logcat del SDK de Android), filtrarlos e inclusive, enviarlos por correo o salvarlos en un archivo. http://code.google.com/p/android-logger/ Lo estamos usando en un proyecto en Schematic, y permite que usuarios no &#8220;techies&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p>Me tope por ahi con esta aplicación bastante útil a mi parecer. Simplemente permite leer los logs (los que se obtendría usando la utilidad logcat del SDK de Android), filtrarlos e inclusive, enviarlos por correo o salvarlos en un archivo.</p>
<p><a href="http://code.google.com/p/android-logger/">http://code.google.com/p/android-logger/</a></p>
<p>Lo estamos usando en un proyecto en Schematic, y permite que usuarios no &#8220;techies&#8221; nos envíen los logs en caso de algún crash de la aplicación. Como la aplicación está aun en &#8220;beta&#8221;, y por lo tanto no disponible en el Android Market, se hacía difícil poder dar soporte en caso de errores de la aplicación.</p>
<p style="text-align: center;"><img class="aligncenter" title="ss1" src="http://lh6.ggpht.com/_ocQeXRd1414/SySebjIjztI/AAAAAAAAADw/ZkwQSfdcINI/s800/logger1.png" alt="" width="320" height="480" /><img class="aligncenter" title="ss2" src="http://lh4.ggpht.com/_ocQeXRd1414/SySebnDVJzI/AAAAAAAAAD0/OkGXyhZVf3g/s800/logger2.png" alt="" width="320" height="480" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.fr4gus.com/2010/10/22/android-logger/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bug de RelativeLayout con fill_parent</title>
		<link>http://www.fr4gus.com/2010/10/18/bug-de-relativelayout-con-fill_parent/</link>
		<comments>http://www.fr4gus.com/2010/10/18/bug-de-relativelayout-con-fill_parent/#comments</comments>
		<pubDate>Mon, 18 Oct 2010 20:18:33 +0000</pubDate>
		<dc:creator>Franklin García</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[comparision]]></category>
		<category><![CDATA[fill_parent]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[LayoutInflater]]></category>
		<category><![CDATA[RelativeLayout]]></category>

		<guid isPermaLink="false">http://blog.fr4gus.com/?p=325</guid>
		<description><![CDATA[Cuando se utiliza de altura y ancho &#8220;fill_parent&#8221; en un RelativeLayout, es probable que le de algunas sorpresas. Si es utilizado directamente en un archivo de layout, es probable que no de mucho problema, pero a la hora de crear componentes a base de este layout (utilizando el LayoutInflater) podrá notar que se comporta muy [...]]]></description>
			<content:encoded><![CDATA[<p>Cuando se utiliza de altura y ancho &#8220;fill_parent&#8221; en un <a href="http://developer.android.com/reference/android/widget/RelativeLayout.html">RelativeLayout</a>, es probable que le de algunas sorpresas.</p>
<p>Si es utilizado directamente en un archivo de layout, es probable que no de mucho problema, pero a la hora de crear componentes a base de este layout (utilizando el <a href="http://developer.android.com/reference/android/view/LayoutInflater.html">LayoutInflater</a>) podrá notar que se comporta muy diferente. Particularmente con las alturas &#8220;ajustables&#8221;.</p>
<p>Buscando la razón me encontre este ticket en los bug reports de Android: <a href="http://code.google.com/p/android/issues/detail?id=1394">http://code.google.com/p/android/issues/detail?id=1394</a> donde básicamente describen este problema y nos dan la solución. Utilizar altura y ancho fijos.</p>
<p>El siguiente layout</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;FrameLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
  android:layout_width=&quot;50dip&quot;
  android:layout_height=&quot;50dip&quot;
&gt;
	&lt;RelativeLayout
	  android:background=&quot;#FFFFFF&quot;
	  android:layout_width=&quot;fill_parent&quot;
	  android:layout_height=&quot;fill_parent&quot;&gt;

	  &lt;TextView
	  	android:text=&quot;1&quot;
	  	android:textColor=&quot;#FF0000&quot;
	  	android:layout_alignParentTop=&quot;true&quot;
	  	android:layout_alignParentLeft=&quot;true&quot;
	  	android:layout_width=&quot;wrap_content&quot;
	  	android:layout_height=&quot;wrap_content&quot; /&gt;
	  &lt;TextView
	  	android:text=&quot;2&quot;
	  	android:textColor=&quot;#FF0000&quot;
	  	android:layout_alignParentTop=&quot;true&quot;
	  	android:layout_alignParentRight=&quot;true&quot;
	  	android:layout_width=&quot;wrap_content&quot;
	  	android:layout_height=&quot;wrap_content&quot; /&gt;
	  &lt;TextView
	  	android:text=&quot;3&quot;
	  	android:textColor=&quot;#0000FF&quot;
	  	android:layout_alignParentBottom=&quot;true&quot;
	  	android:layout_alignParentRight=&quot;true&quot;
	  	android:layout_width=&quot;wrap_content&quot;
	  	android:layout_height=&quot;wrap_content&quot; /&gt;
	  &lt;TextView
	  	android:text=&quot;4&quot;
	  	android:textColor=&quot;#0000FF&quot;
	  	android:layout_alignParentBottom=&quot;true&quot;
	  	android:layout_alignParentLeft=&quot;true&quot;
	  	android:layout_width=&quot;wrap_content&quot;
	  	android:layout_height=&quot;wrap_content&quot; /&gt;
	&lt;/RelativeLayout&gt;
&lt;/FrameLayout&gt;
</pre>
<p>Da como resultado este posicionamiento, normal, en el preview del layout en Eclipse.<br />
<a href="http://www.fr4gus.com/wp-content/uploads/2010/10/relative_layout_preview.png"><img src="http://www.fr4gus.com/wp-content/uploads/2010/10/relative_layout_preview.png" alt="" title="relative_layout_preview" width="240" height="240" class="aligncenter size-full wp-image-358" /></a></p>
<p>Hemos utilizado un GridView con 10 Views que utilizan el layout anterior. Pero en vez de mostrarlo similar que en el preview, se muesta de la siguiente manera en un teléfono:<br />
<a href="http://www.fr4gus.com/wp-content/uploads/2010/10/relative_layout_fill_parent.png"><img src="http://www.fr4gus.com/wp-content/uploads/2010/10/relative_layout_fill_parent.png" alt="" title="relative_layout_fill_parent" width="480" height="280" class="aligncenter size-full wp-image-359" /></a></p>
<p>Como se citó anteriormente, al momento de ponerle altura fija directamente en la configuración del RelativeLayout, se resuelve el problema.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;FrameLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
  android:layout_width=&quot;wrap_content&quot;
  android:layout_height=&quot;wrap_content&quot;
&gt;
	&lt;RelativeLayout
	  android:background=&quot;#FFFFFF&quot;
	  android:layout_width=&quot;50dip&quot;
	  android:layout_height=&quot;50dip&quot;&gt;

	  &lt;TextView
	  	android:text=&quot;1&quot;
	  	android:textColor=&quot;#FF0000&quot;
	  	android:layout_alignParentTop=&quot;true&quot;
	  	android:layout_alignParentLeft=&quot;true&quot;
	  	android:layout_width=&quot;wrap_content&quot;
	  	android:layout_height=&quot;wrap_content&quot; /&gt;
	  &lt;TextView
	  	android:text=&quot;2&quot;
	  	android:textColor=&quot;#FF0000&quot;
	  	android:layout_alignParentTop=&quot;true&quot;
	  	android:layout_alignParentRight=&quot;true&quot;
	  	android:layout_width=&quot;wrap_content&quot;
	  	android:layout_height=&quot;wrap_content&quot; /&gt;
	  &lt;TextView
	  	android:text=&quot;3&quot;
	  	android:textColor=&quot;#0000FF&quot;
	  	android:layout_alignParentBottom=&quot;true&quot;
	  	android:layout_alignParentRight=&quot;true&quot;
	  	android:layout_width=&quot;wrap_content&quot;
	  	android:layout_height=&quot;wrap_content&quot; /&gt;
	  &lt;TextView
	  	android:text=&quot;4&quot;
	  	android:textColor=&quot;#0000FF&quot;
	  	android:layout_alignParentBottom=&quot;true&quot;
	  	android:layout_alignParentLeft=&quot;true&quot;
	  	android:layout_width=&quot;wrap_content&quot;
	  	android:layout_height=&quot;wrap_content&quot; /&gt;
	&lt;/RelativeLayout&gt;
&lt;/FrameLayout&gt;
</pre>
<p>Dando como resultado, el layout esperado:<br />
<a href="http://www.fr4gus.com/wp-content/uploads/2010/10/relative_layout_50dip.png"><img src="http://www.fr4gus.com/wp-content/uploads/2010/10/relative_layout_50dip.png" alt="" title="relative_layout_50dip" width="480" height="280" class="aligncenter size-full wp-image-360" /></a></p>
<p>Otra nota curiosa, es que esto solo es posible verlo en telefonos reales, ya que en los emuladores este problema no es posible replicarlo. Personalmente había visto este problema ocurrir solo en Android 2.1 (Eclair), pero a la hora de preparar este ejemplo, lo pude replicar tanto en un telefono con Eclair como con FroYo.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fr4gus.com/2010/10/18/bug-de-relativelayout-con-fill_parent/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android para todos los dispositivos</title>
		<link>http://www.fr4gus.com/2010/06/03/android-para-todos-dispositivos-p1/</link>
		<comments>http://www.fr4gus.com/2010/06/03/android-para-todos-dispositivos-p1/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 04:55:08 +0000</pubDate>
		<dc:creator>Franklin García</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[aspect ratio]]></category>
		<category><![CDATA[dpi]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[IO2010]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[multiple screen]]></category>
		<category><![CDATA[resolution]]></category>

		<guid isPermaLink="false">http://blog.fr4gus.com/?p=280</guid>
		<description><![CDATA[Parte 1 &#8211; Recursos Introducción Durante el Google IO 2010, una de las charlas que más me interesó fue la impartida por Justin Mattson llamada &#8220;Casting a wide net: how to target all Android devices&#8221; que trató de como hacer aplicaciones, que puedan ser usadas exitosamente, en todos los dispositivos Android. Puede que suene un [...]]]></description>
			<content:encoded><![CDATA[<h1>Parte 1 &#8211; Recursos</h1>
<h2>Introducción</h2>
<p>Durante el Google IO 2010, una de las charlas que más me interesó fue la impartida por Justin Mattson llamada &#8220;<em>Casting a wide net: how to target all Android devices</em>&#8221; que trató de como hacer aplicaciones, que puedan ser usadas exitosamente, en todos los dispositivos Android. Puede que suene un poco audaz, pero sí es posible. Tenemos que tener claro que no para todas las aplicaciones es posible, pero se pueden tomar algunos consejos para poder permitir a la aplicación ser ejecutada, al menos, en la mayor cantidad de dispositivos posible.</p>
<p><span style="font-size: 13.3333px;">Lamentablemente la charla fue corta, para la importancia del contenido por lo que quiero hacer esta serie de entradas, para explicar un poco más a detalle lo explicado en la presentación, basado tanto en el contenido de la misma, como en mi experiencia. Para ello, les explicaré con un ejemplo llamado Blue Monkey Eyes, una aplicación que hice para poder entender bien estos conceptos. La aplicación es bastante absurda, ya que no hace más que hacer ruidos, pero lo que veremos es el cómo se hizo.</span></p>
<p>Para esta primera parte discutiremos lo siguiente:</p>
<ul>
<li><a href="#densidad">Densidad o DPI</a> (de sus siglas en inglés Dots per Inch)</li>
<li><a href="#resolucion">Resolución de pantallas</a> (alto por ancho)</li>
<li><a href="#orientacion">Orientación</a> (horizontal y vertical)</li>
</ul>
<h2><a name="densidad"></a>Densidad de Pantallas</h2>
<p>En pocas palabras, cuantos puntos por pulgada hay en una superficie (dpi). No hay que confundir pixeles por pulgada (ppi). La importancia de la densidad es que esto permite que al crear una  imagen o texto tenga el mismo tamaño real, sin importar la resolución o tamaño físico de la pantalla. Veamos la siguiente imagen:</p>
<div class="wp-caption alignnone" style="width: 510px"><a href="http://developer.android.com/guide/practices/screens_support.html"><img title="Independencia de Densidad" src="http://developer.android.com/images/screens_support/dip.png" alt="" width="500" height="273" /></a>
<p class="wp-caption-text">Ejemplo de independencia de densidad en WVGA de alta densidad (izq), HVGA media densidad (centro), y QVGA baja densidad (der). Tomado de Android Support Screens</p>
</div>
<p>Es importante que a la hora de diseñar los recursos de la aplicación, se defina bien los tamaños que se soportarán para así determinar la densidad o densidades y hacer un conjunto de recursos por cada uno. La plataforma Android nos permite definir carpetas por densidad de pantalla usando &#8220;calificadores&#8221; o &#8220;sufijos&#8221;. Para la densidad, están definidos 4 calificadores para la carpeta <strong><span style="color: #3366ff;">drawable</span></strong>:&#8221;-hdpi&#8221;, &#8220;-mdpi&#8221;, &#8220;-ldpi&#8221; y &#8220;nodpi&#8221;. Simplemente creamos las carpetas &#8220;<span style="color: #3366ff;"><strong>drawable-[<span style="color: #000000;">hpdi</span>|<span style="color: #800000;">mdpi</span>|<span style="color: #003300;">ldpi</span>]</strong></span>&#8221; según las densidades que se soportarán. Es importante que los recursos mantengan el nombre a travéz de los folders, para que así la plataforma pueda hacer la selección sin problemas.</p>
<div id="attachment_301" class="wp-caption alignleft" style="width: 418px"><img class="size-full wp-image-301 " title="Estructura de carpetas" src="http://fr4gus.com/wp-content/uploads/2010/06/folder_structure.png" alt="Estructura de carpetas" width="408" height="248" />
<p class="wp-caption-text">Estructura de carpetas</p>
</div>
<p style="text-align: center;">
<p>Existe una &#8220;pulga&#8221; o &#8220;<em>bug</em>&#8221; en la version 1.5 (SDK 3), ya que esta estructura de carpetas fue introducida hasta la versión 1.6. El problema con 1.5 es que puede escoger inadecuadamente el recurso, aunque éste se encuentre en la carpeta &#8220;drawable&#8221;. Para resolver esto, se debe agregar otro sufijo (después de -[hdpi|mdpi|ldpi]) a las carpetas que serán utilizadas para soportar diferentes densidades en dispositivos mayores a la version 3 del SDK. El sufijo a utilizar es &#8220;-v[4...n]&#8221; donde n es el número de SDK mínimo que la aplicación soportará para multi densidad y se deja &#8220;drawable&#8221; para que el SDK 3 tome las imágenes. Creo que esta mejor explicado en <a href="http://developer.android.com/guide/practices/screens_support.html#qualifiers">http://developer.android.com/guide/practices/screens_support.html#qualifiers</a>.</p>
<h2><a name="resolucion"></a>Resolución de Pantallas</h2>
<p>Actualmente, diferentes compañías han adoptado Android para la fabricación de dispositivos móviles, algunos de ellos son HTC (que sacó el primer dispositivo Android), Samsumg, Motorola entre otros. Debido a que no existe una estandariación en cuanto al hardware que soporta Android, tenemos a disposición diferentes modelos para diferentes necesidades. La visión de Google en cuanto dejar abierto a la innovación queda muy claro a este punto.  Tenemos los dispositivos tipo tablets a la vuelta de la esquina y no muy lejos Google TV que también se basará en android.</p>
<p>En la documentación oficial de Android se encuentra disponible una guía para poder soportar múltiples pantallas (<a href="http://developer.android.com/guide/practices/screens_support.html">http://developer.android.com/guide/practices/screens_support.html</a>). Ahí definen &#8220;cajones&#8221; de como se dividen las pantallas y como se distribuye las densidades en ellas formando la siguiente matriz:</p>
<table id="screens-table" style="margin-top: 2em;">
<tbody>
<tr>
<td></td>
<td style="background-color: #f3f3f3;">Baja densidad  (120), <em>ldpi</em></td>
<td style="background-color: #f3f3f3;">Densidad Media (160), <em>mdpi</em></td>
<td style="background-color: #f3f3f3;">Alta densidad (240), <em>hdpi</em></td>
</tr>
<tr>
<td style="background-color: #f3f3f3;"><em>Pantalla Pequeña</em></td>
<td style="font-size: .9em;">
<ul style="padding: 0;">
<li style="margin: 0 0 0 1em; padding: .25em 0 0 0; font-size: .9em;">QVGA (240&#215;320), 2.6&#8243;-3.0&#8243; diagonal</li>
</ul>
</td>
<td></td>
<td></td>
</tr>
<tr>
<td style="background-color: #f3f3f3;"><em>Pantalla Normal</em></td>
<td style="font-size: .9em;">
<ul style="padding: 0;">
<li style="margin: 0 0 0 1em; padding: .25em 0 0 0; font-size: .9em;">WQVGA (240&#215;400), 3.2&#8243;-3.5&#8243; diagonal</li>
<li style="margin: 0 0 0 1em; padding: .25em 0 0 0; font-size: .9em;">FWQVGA (240&#215;432), 3.5&#8243;-3.8&#8243; diagonal</li>
</ul>
</td>
<td style="font-size: .9em; background-color: #ffe;">
<ul style="padding: 0;">
<li style="margin: 0 0 0 1em; padding: .25em 0 0 0; font-size: .9em;">HVGA (320&#215;480), 3.0&#8243;-3.5&#8243; diagonal</li>
</ul>
</td>
<td style="font-size: .9em;">
<ul style="padding: 0;">
<li style="margin: 0 0 0 1em; padding: .25em 0 0 0; font-size: .9em;">WVGA (480&#215;800), 3.3&#8243;-4.0&#8243; diagonal</li>
<li style="margin: 0 0 0 1em; padding: .25em 0 0 0; font-size: .9em;">FWVGA (480&#215;854), 3.5&#8243;-4.0&#8243; diagonal</li>
</ul>
</td>
</tr>
<tr>
<td style="background-color: #f3f3f3;"><em>Pantalla Grande</em></td>
<td></td>
<td style="font-size: .9em;">
<ul style="padding: 0;">
<li style="margin: 0 0 0 1em; padding: .25em 0 0 0; font-size: .9em;">WVGA (480&#215;800), 4.8&#8243;-5.5&#8243; diagonal</li>
<li style="margin: 0 0 0 1em; padding: .25em 0 0 0; font-size: .9em;">FWVGA (480&#215;854), 5.0&#8243;-5.8&#8243; diagonal</li>
</ul>
</td>
<td></td>
</tr>
</tbody>
</table>
<p>Android ofrece los calificadores &#8220;small&#8221;, &#8220;normal&#8221; y &#8220;large&#8221; para poder separar los recursos de acuerdo al tamaño de la pantalla.</p>
<h2><a name="orientacion"></a> Orientación Horizontal y Vertical</h2>
<p>Tal vez una de las cualidades más discutidas en la comunidad Android, es la capacidad de cambiar el aspecto cuando se tiene el dispositivo de forma vertical o horizontal. Dentro de las preguntas más frecuentes que se puede leer en el grupo de usuarios de Android es como desactivar esta facilidad. Lo que recomienda Google es no pelear con él sino aprender a manejarlo.</p>
<p>Hay que tener bien claro que estoy no aplica para todas las aplicaciones. Por ejemplo, algunos juegos ocupan que a pesar de que se cambie la orientación del dispositivo, se mantenga todo como está, para evitar una experiencia de usuario pobre y por que el <em>game play</em> lo requiere así.</p>
<p>Si su aplicación requiere que se maneje tanto una orientación vertical (<em>portrait</em>) como horizontal (<em>landscape</em>), puede utilizar los calificadores &#8220;-port&#8221; y &#8220;-land&#8221; para la carpeta de layout.</p>
<p>La carpeta debiera verse así:</p>
<div id="attachment_307" class="wp-caption aligncenter" style="width: 317px"><img class="size-full wp-image-307" title="layout_folders" src="http://fr4gus.com/wp-content/uploads/2010/06/layout_folders.png" alt="" width="307" height="209" />
<p class="wp-caption-text">Folders Layout con calificador -land</p>
</div>
<p>Dando como resultado que la aplicación se vea así en ambas posiciones:</p>
<div id="attachment_305" class="wp-caption aligncenter" style="width: 384px"><img class="size-full wp-image-305" title="Layout Default" src="http://fr4gus.com/wp-content/uploads/2010/06/obey1.png" alt="" width="374" height="533" />
<p class="wp-caption-text">Posición por defecto, Vertical</p>
</div>
<div id="attachment_306" class="wp-caption aligncenter" style="width: 560px"><img class="size-large wp-image-306" title="Landscape" src="http://fr4gus.com/wp-content/uploads/2010/06/obey2-550x327.png" alt="" width="550" height="327" />
<p class="wp-caption-text">Horizontal</p>
</div>
<p><span style="font-size: 13.3333px;">Aqui el XML de ambos layouts. </span></p>
<p><span style="font-size: 13.3333px;">Layout por defecto de Obey the Monkey</span></p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
	xmlns:app=&quot;http://schemas.android.com/apk/res/com.fr4gus.android.blueeyesmonkey&quot;
	android:orientation=&quot;vertical&quot;
        android:layout_width=&quot;fill_parent&quot;
	android:layout_height=&quot;fill_parent&quot;&gt;
	&lt;com.admob.android.ads.AdView android:id=&quot;@+id/ad&quot;
		android:layout_width=&quot;fill_parent&quot;
		android:layout_height=&quot;wrap_content&quot;
		app:backgroundColor=&quot;#000000&quot;
		app:primaryTextColor=&quot;#FFFFFF&quot;
		app:secondaryTextColor=&quot;#CCCCCC&quot;
		app:refreshInterval=&quot;15&quot;
		app:keywords=&quot;Android Silly Application&quot; /&gt;

	&lt;ImageView android:id=&quot;@+id/ImageMonkey&quot;
		android:layout_width=&quot;wrap_content&quot;
		android:layout_height=&quot;wrap_content&quot;
		android:src=&quot;@drawable/monkey_inactive&quot;
		android:baselineAlignBottom=&quot;true&quot;
		android:layout_gravity=&quot;center_vertical|center_horizontal&quot; /&gt;

	&lt;LinearLayout android:id=&quot;@+id/ButtonsLayout&quot;
		android:layout_width=&quot;fill_parent&quot;
		android:orientation=&quot;vertical&quot;
		android:layout_height=&quot;wrap_content&quot;
		android:layout_gravity=&quot;bottom|center_horizontal&quot;&gt;
		&lt;Button android:id=&quot;@+id/ObeyButton&quot; android:layout_width=&quot;fill_parent&quot;
			android:layout_height=&quot;wrap_content&quot;
			android:text=&quot;@string/obeyButtonLabel&quot;
			android:gravity=&quot;center_horizontal|center_vertical&quot;
			android:background=&quot;@drawable/button_states&quot;
			android:textColor=&quot;#FFFFFF&quot; /&gt;
		&lt;Button android:id=&quot;@+id/ListenButton&quot;
			android:layout_width=&quot;fill_parent&quot;
			android:layout_height=&quot;wrap_content&quot;
			android:text=&quot;@string/listenButtonLabel&quot;
			android:typeface=&quot;normal&quot; android:textColor=&quot;#FFFFFF&quot;
			android:background=&quot;@drawable/button_states&quot; /&gt;
	&lt;/LinearLayout&gt;
&lt;/LinearLayout&gt;
</pre>
<p>Layout en modo <em>landscape</em> de Obey the Monkey</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
	xmlns:app=&quot;http://schemas.android.com/apk/res/com.fr4gus.android.blueeyesmonkey&quot;
	android:orientation=&quot;vertical&quot; android:layout_gravity=&quot;center_vertical|center_horizontal&quot;
	android:layout_height=&quot;fill_parent&quot; android:layout_width=&quot;fill_parent&quot;&gt;
	&lt;com.admob.android.ads.AdView android:id=&quot;@+id/ad&quot;
		android:layout_width=&quot;fill_parent&quot; android:layout_height=&quot;wrap_content&quot;
		app:backgroundColor=&quot;#000000&quot; app:primaryTextColor=&quot;#FFFFFF&quot;
		app:secondaryTextColor=&quot;#CCCCCC&quot; app:refreshInterval=&quot;15&quot;
		app:keywords=&quot;Android Silly Application&quot; /&gt;
	&lt;LinearLayout android:id=&quot;@+id/contentLayout&quot;
		android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot;
		android:orientation=&quot;horizontal&quot; android:layout_gravity=&quot;right|center_vertical&quot;&gt;
		&lt;ImageView android:id=&quot;@+id/ImageMonkey&quot;
			android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot;
			android:src=&quot;@drawable/monkey_inactive&quot; android:layout_gravity=&quot;center_horizontal|center_vertical&quot;&gt;&lt;/ImageView&gt;
		&lt;LinearLayout android:id=&quot;@+id/ButtonsLayout&quot;
			android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot;
			android:orientation=&quot;vertical&quot; android:layout_gravity=&quot;right|center_vertical&quot;&gt;
			&lt;Button android:id=&quot;@+id/ObeyButton&quot; android:layout_width=&quot;fill_parent&quot;
				android:layout_height=&quot;wrap_content&quot; android:text=&quot;@string/obeyButtonLabel&quot;
				android:gravity=&quot;center_horizontal|center_vertical&quot;
				android:textColor=&quot;#FFFFFF&quot; android:layout_gravity=&quot;center_vertical|center_horizontal&quot;
				android:background=&quot;@drawable/button_states&quot;&gt;&lt;/Button&gt;
			&lt;Button android:id=&quot;@+id/ListenButton&quot; android:layout_width=&quot;fill_parent&quot;
				android:layout_height=&quot;wrap_content&quot; android:text=&quot;@string/listenButtonLabel&quot;
				android:textColor=&quot;#FFFFFF&quot; android:typeface=&quot;normal&quot;
				android:layout_gravity=&quot;center_vertical|center_horizontal&quot;
				android:background=&quot;@drawable/button_states&quot;&gt;&lt;/Button&gt;
		&lt;/LinearLayout&gt;

	&lt;/LinearLayout&gt;
&lt;/LinearLayout&gt;
</pre>
<h2>Resumen</h2>
<p>La importancia de poder soportar diferentes pantallas, radica principalmente en el mercado meta de su aplicación. Entre más dispositivos soporte, a más usuarios podra llegar. Pero debe tomar en cuenta los requerimientos de la aplicación así como velar que la experiencia de usuario sea grata también.</p>
<p>Para la segunda parte revisaremos como manejar las diferentes versiones de SDKs y como podemos afrontar el problema de objetos o métodos disponibles en uno e innexistentes en otros.</p>
<h2>Calificadores vistos:</h2>
<table>
<tbody>
<tr>
<th>Pantalla</th>
<th>Calificador o Sufijo</th>
<th>Descripción</th>
</tr>
<tr>
<td rowspan="3">Tamaño</td>
<td><code>small</code></td>
<td>Recursos para pantallas pequeñas, como QVGA en baja densidad</td>
</tr>
<tr>
<td><code>normal</code></td>
<td>Recursos para pantallas normales, como las pantallas del  T-Mobile G1/HTC Magic o equivalente</td>
</tr>
<tr>
<td><code>large</code></td>
<td>Recursos para pantResources for large screens. Typical example is a tablet like device.</td>
</tr>
<tr>
<td rowspan="4">Densidad</td>
<td><code>ldpi</code></td>
<td>Recursos de baja densidad (entre  100 y140 dpi).</td>
</tr>
<tr>
<td><code>mdpi</code></td>
<td>Recursos de mediana densidad  (entre 140 y 180 dpi).</td>
</tr>
<tr>
<td><code>hdpi</code></td>
<td>Recursos de alta densidad (entre 190 y 250 dpi)</td>
</tr>
<tr>
<td><code>nodpi</code></td>
<td>Recursos independientes de densidad. La plataforma no intentara escalar automáticamente recursos bajo este calificador sin importar la densidad de la pantalla actual.</td>
</tr>
<tr>
<td rowspan="2">Relación de Aspecto</td>
<td><code>long</code></td>
<td>Recursos para pantalla de cualquier tamaño y densidad, donde la relación de acpecto tanto en alto (modo portrait)  o ancho (modo landscape) sea significativamente mayor que la configuración base de la pantalla.</td>
</tr>
<tr>
<td><code>notlong</code></td>
<td>Recursos para pantallas donde la relación de aspecto es similar a la configuración base de la pantalla.</td>
</tr>
<tr>
<td>Versión de Plataforma</td>
<td><code>v&lt;api-level&gt;</code></td>
<td>Recursos que solo se usarán para una versión específica del API o mayor. Por ejemnplo, si su aplicación corre en Android 1.5 (API Level 3) y Android 1.5 (API Level 4 o<span style="font-size: 10.8333px;">mayor) usted puede usar el calificador -v4 para excluir aquellos recursos cuando la aplicación va a correr Android  1.5 (API Level 3).</span></td>
</tr>
<tr>
<td>Vertical</td>
<td><code>port</code></td>
<td>Recursos que se utilizarán para la pantalla en modo <em>portrait </em></td>
</tr>
<tr>
<td>Horizontal</td>
<td><span style="font-family: monospace;">land</span></td>
<td>Recursos que se utilizarán para la pantalla en modo <em>landscape</em></td>
</tr>
</tbody>
</table>
<h2>Links importantes</h2>
<ul>
<li>[Inglés]Proveyendo Recursos: <a href="http://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources">http://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources</a></li>
<li>[Inglés]Mejores Practicas &#8211; Soportando múltiples pantallas: <a href="http://developer.android.com/guide/practices/screens_support.html">http://developer.android.com/guide/practices/screens_support.html</a></li>
<li>[Inglés]Justin Mattson &#8211; &#8220;<em>Casting a wide net: how to target all Android devices</em>&#8220; <a title="Casting a wide net: how to target all Android devices" href="http://">https://wave.google.com/wave/#restored:wave:googlewave.com!w%252BfZ2urbZk7o</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.fr4gus.com/2010/06/03/android-para-todos-dispositivos-p1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Andriod en Google IO 2010</title>
		<link>http://www.fr4gus.com/2010/05/22/andriod-en-google-io-2010/</link>
		<comments>http://www.fr4gus.com/2010/05/22/andriod-en-google-io-2010/#comments</comments>
		<pubDate>Sun, 23 May 2010 03:31:17 +0000</pubDate>
		<dc:creator>Franklin García</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Desarrollo de Software]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[HTC]]></category>
		<category><![CDATA[IO2010]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Motorola]]></category>

		<guid isPermaLink="false">http://blog.fr4gus.com/?p=261</guid>
		<description><![CDATA[Ayer recién llegaba de la extraordinaria conferencia Google IO 2010. Definitivamente fuimos muy afortunados los que tuvimos el privilegio de asistir, y no sólo por los dos teléfonos que nos regalaron: Un Motorola Droid (Verizon) y un HTC Evo 4g (Sprint), sino también por la cantidad de información que recibimos, así como los anuncios sobre [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="size-large wp-image-263 aligncenter" title="GoogleIO Screen" src="http://www.fr4gus.com/wp-content/uploads/2010/05/2010-05-20-08.22.43-550x410.jpg" alt="" /></p>
<p>Ayer recién llegaba de la extraordinaria conferencia <strong><span style="color: #3366ff;">Google IO 2010</span></strong>. Definitivamente fuimos muy afortunados los que tuvimos el privilegio de asistir, y no sólo por los dos teléfonos que nos regalaron: Un Motorola Droid (Verizon) y un HTC Evo 4g (Sprint), sino también por la cantidad de información que recibimos, así como los anuncios sobre lo que tiene Google para este año, como el Google TV y Android 2.2 (FroYo).</p>
<p>Mi interés en esta conferencia se centra particulamente en el tema de Android, ya que por ahora es en lo que me quiero enfocar y por lo tanto será el tema principal de este post, si quieren tener información más detallada de lo demás que se habló en esta conferencia, no duden de visitar la pagina principal de la conferencia <a href="http://code.google.com/events/io/2010/">aquí</a>. Por aquí me encontré el <a href="http://www.engadget.com/2010/05/20/live-from-the-google-i-o-2010-day-2-keynote/">Live Blog de Endgadget del Keynote del Segundo</a> día.</p>
<p>Lo más destacable de la conferencia, en cuanto a android fue el gran anuncio de la más reciente actualización llamada FroYo, cuya versión numérica es 2.2 ( y para el SDK versión 8). Adjunto aquí un resumen de las características:</p>
<ol>
<li>Compilador Just-in-Time (JIT) que incrementara la velocidad del sistema de 2x a 5x.</li>
<li>Alrededor de 20 características empresariales, incluyendo una mejor integración con Exchange, un API para  administración del dispositivo (por ejemplo políticas de seguridad), respaldo de datos personales para transferirlos a otro dispositivo android.</li>
<li>Nuevo API para mensajería Cloud-to-Device, algo más allá de notificaciones push.</li>
<li>WiFi <a href="http://en.wikipedia.org/wiki/Tethering">tethering</a> y WiFi HotSpot. Esto permitirá que dispositivos con capacidad WiFi puedan conectarse al dispositivo Android y poder acceder a Internet a través de él (usando la conexión de datos del servicio móvil).</li>
<li>Además, actualización al Android Market para poder buscar mejor las aplicaciones. Android Market también podrá ser accedido mendiante una computadora. Pero aun mejor usted podrá bajar la aplicaciónes a su PC  e instalarlas inmediatamente a su dispositivo Android de su elección, sin ocupar conectar el Andriod a su PC (ambos ocupan conexión de datos a Internet).</li>
<li>Es importante recalcar que Google TV soportará aplicaciones Android y estará integrado igualmente con Android Market, por lo que la funcionalidad anterior también estará disponible para Google TV.</li>
</ol>
<p>Durante el resto de los días estas fueron las charlas relacionadas a Android:</p>
<table>
<tbody>
<tr>
<td><a href="http://code.google.com/events/io/2010/sessions/beginners-guide-android.html">A beginner&#8217;s guide to Android</a></td>
<td>Si usted no sabía mucho sobre android y quiere aprender esta era la charla introductoria.</td>
</tr>
<tr>
<td><a href="http://code.google.com/events/io/2010/sessions/writing-real-time-games-android.html">Writing real-time games for Android redux</a></td>
<td>Excelente charla sobre recomendaciones y mejores prácticas para iniciarse en el desarrollo de juegos para Android.</td>
</tr>
<tr>
<td><a href="http://code.google.com/events/io/2010/sessions/world-of-listview-android.html">The world of ListView</a></td>
<td>Como sacarle el mejor provecho a este componente visual, mejores prácticas para poder mostrar adecuadamente el contenido en él y además cuando se debe utilizar un ListView y cuando un Scroll View.</td>
</tr>
<tr>
<td><a href="http://code.google.com/events/io/2010/sessions/casting-wide-net-android-devices.html">Casting a wide net: how to target all Android devices</a></td>
<td>Tal vez una de los requerimientos más importantes a la hora de desarrollar para Android. Debido a la independencia entre Android y los fabricantes de dispositivos móviles, la fragmentación en Android es compleja pero resulta una ventaja para el usuario ya quue puede escoger el dispositivo de acuerdo a sus necesidades. El reto está para los desarrolladores afrontar la fragmentación no como un problema sino como un &#8220;feature&#8221; más a la hora de diseñar y crear aplicaciones. Durante la charla se dieron bastantes tips sobre como lograr abarcar la mayor cantidad de pantallas, resoluciones y densidades. Espero poder profundizar en este tema en próximos post.</td>
</tr>
<tr>
<td><a href="http://code.google.com/events/io/2010/sessions/android-ui-design-patterns.html">Android UI design patterns</a></td>
<td>Una charla muy clara sobre las mejores prácticas y patrones a la hora de diseñar interfaces para android. Si bien se podría decir que esto está más orientado para diseñadores y expertos en UX, es un tema importante que los desarrolladores serios deben comprender.</td>
</tr>
<tr>
<td><a href="http://code.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html">Developing Android REST client applications</a></td>
<td></td>
</tr>
<tr>
<td><a href="http://code.google.com/events/io/2010/sessions/jit-compiler-androids-dalvik-vm.html">A JIT Compiler for Android&#8217;s Dalvik VM</a></td>
<td>Muy buena reseña sobre como el compilador JIT, que estará disponible a partir de FroYo, mejorará el desempeño del sistema y de las aplicaciónes. Se explicó los métodos para optimizar las aplicaciones, ventajas y desventajas.</td>
</tr>
<tr>
<td><a href="http://code.google.com/events/io/2010/sessions/writing-zippy-android-apps.html">Writing zippy Android apps</a></td>
<td>Muy buena charla de mejores prácticas para desarrollar en Android en general.</td>
</tr>
<tr>
<td><a href="http://code.google.com/events/io/2010/sessions/android-audio-techniques.html">Advanced Android audio techniques</a></td>
<td></td>
</tr>
<tr>
<td><a href="http://code.google.com/events/io/2010/sessions/push-applications-android.html">Building push applications for Android</a></td>
<td></td>
</tr>
<tr>
<td><a href="http://code.google.com/events/io/2010/sessions/fireside-chat-android-team.html">Fireside chat with the Android team</a></td>
<td></td>
</tr>
<tr>
<td><a href="http://code.google.com/events/io/2010/sessions/fireside-chat-android-handset-manufacturers.html">Fireside chat with Android handset manufacturers</a></td>
<td></td>
</tr>
<tr>
<td><a href="http://code.google.com/events/io/2010/sessions/analyzing-monetizing-mobile-apps.html">Analyzing and monetizing your Android &amp; iPhone apps</a></td>
<td></td>
</tr>
</tbody>
</table>
<p>También me parece importante rescatar la actividad que hubo el Miércoles después de las charlas, de verdad una actividad para socializar muy interesante y entretenida.</p>
<p>Aquí termina mi resumen de Android en Google IO 2010. No quise hacer un post muy largo, para motivarlos a buscar información detallada en el sitio de Google y otro montón de fuentes disponibles en la Web.</p>
<p>Espero volver el próximo año y seguir trabajando en aplicaciones para Android, y tal vez algún día llegar como expositor u orador.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fr4gus.com/2010/05/22/andriod-en-google-io-2010/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

