miércoles, 16 de marzo de 2011

Acceder al código fuente de Android

Cuando estamos programando en Android es muy útil si queremos ver el funcionamiento de un componente de Android buscarlo en la API. Sin embargo aún más cómodo y mas potente es poder acceder al código base, como si de una clase de nuestro proyecto se tratase, esto es, acceder a los ficheros .class que incluye nuestro android.jar.

La forma de hacerlo con el IDE Eclipse es instalando un plugin tal y como explican aqui
An easier way of getting the source into your Eclipse installation is to use the "Android Sources" plugin from http://code.google.com/p/adt-addons/ . Haris Peco maintains plugins with gives access to the Android Source code. Using the Eclipse update manager install two of his plugins. Update site: "http://adt-addons.googlecode.com/svn/trunk/source/com.android.ide.eclipse.source.update" and "http://adt-addons.googlecode.com/svn/trunk/binedit/com.android.ide.eclipse.binedit.update".

Me ha pasado que no funcionaba a veces el plugin, por lo que manualmente nos vamos a las propiedades del proyecto y en las librerias adjuntas, editamos la de android y le ponemos como source: I:/Eclipse/plugins/com.android.ide.eclipse.source_8.0.1.201012181425/4/sources.zip

En la web también explican como acceder mediante Git al proyecto de código abierto de Android, hacer los cambios en el código que queramos y compilar el proyecto. Para de este modo customizar la versión de Android y si nos encontramos iluminados mejorar algún aspecto y comunicarlo a Google.


martes, 1 de marzo de 2011

Buscar información en la Red de Redes.

Uno de los aspectos más importantes en que ha cambiado Internet durante todos estos años, es la forma que tenemos para descubrir cosas nuevas. Antes este lugar lo ocupaba la televisión, las revistas, los periódicos. Desde la llegada de Internet a nuestra cotidianidad, a mediados de los 90s, el descubrir nueva música, películas y expresiones culturales en general, se transformo en una búsqueda activa. En un inexistente mapa del tesoro que se encontraba disperso en Yahoo o Altavista. Hasta que años después, el mensajero cambio de nombre y de algoritmo, y descubríamos las cosas en Google. Nos convertíamos así en cartógrafos, en descubridores, en navegantes. Había que tomar el lápiz para dibujar el camino.

Descubríamos porque buscábamos.

Pero poco a poco fueron apareciendo sitios que buscaban por nosotros. Que seleccionaban y nos regalaban una buena cantidad de recursos. Fue así como Internet se llenó de cartógrafos que nos indicaban un posible camino.

Por otro lado las redes sociales han cambiado el modo en que podemos acceder a la información, que al fin y al cabo la componen las vivencias de todos y cada uno de nosotros.

Estas redes aparecen en diversos contextos, y me sorprende ver el gran apoyo que ha supuesto a la comunicación en las últimas revoluciones de los países Árabes. Donde una población en busca de la libertad, ha podido expresarse libremente y comunicarse por medios como Twitter. Encontrando esa ansiada información, y demostrando como su acceso es vital para un buen funcionamiento global. Poniendo de manifiesto y de forma coherente que la tecnología mejora nuestra vidas.

Es importante encontrar "nuestro camino" y en el caso de Internet lo tenemos a un par de clicks, increíbles guías nos ofrecen sus blogs, tweets, foros, etc. Y nos ayudan a conocer sitios y experiencias que de otro modo serian difícilmente accesibles. Siempre teniendo cuidado de separar la paja, y no dejarnos caer en los grandes "vacíos" de esta ruta trazada cual descubridor de nuevos mundos.

miércoles, 23 de febrero de 2011

Manejo de Hilos en Android

Uno de los mayores quebraderos de cabeza en Android es el manejo de hilos.
No es posible acceder a las variables de la UI desde un hilo diferente del principal. Por tanto si después de realizar una operacion pesada(una comunicacion por red, acceso al GPS...) queremos actualizar un textview, debemos de pasar esa operacion dentro de un runnable al handler de la Activity. El handler es un objeto de la clase Handler, que una vez declarado en la clase principal, en nuestro ejemplo una Activity, permite interactuar con sus variables.


public class MyActivity extends Activity {
[ . . . ]
// Need handler for callbacks to the UI thread
final Handler mHandler = new Handler();

// Create runnable for posting
final Runnable mUpdateResults = new Runnable() {
public void run() {
updateResultsInUi
();
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

[ . . . ]
}

protected void startLongRunningOperation() {

// Fire off a thread to do some work that we shouldn't do directly in the UI thread
Thread t = new Thread() {
public void run() {
mResults
= doSomethingExpensive();
mHandler
.post(mUpdateResults);
}
};
t
.start();
}

private void updateResultsInUi() {

// Back in the UI thread -- update our UI elements based on the data in mResults
[ . . . ]
}
}

Otra forma de abordar el problema es mediante el uso de mensajes de nuevo con la clase handler. Como bien indica el SDK de android:

There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.

En este ejemplo tan sencillo, nos interesa utilizar el handler para pasar el control del programa desde el hilo que realiza la operacion en el background a el hilo principal, para que actualice el UI. Es decir, como ya hemos mencionado, no sería posible modificar el UI desde el hilo secundario, sino que tenemos que llamar al hilo principal(mediante el objeto hanlder)para que se ocupe de ello. El siguiente código NO SERIA CORRECTO:

protected void startLongRunningOperation() {

// Fire off a thread to do some work that we shouldn't do directly in the UI thread
Thread t = new Thread() {
public void run() {
mResults
= doSomethingExpensive();
updateResultsInUi
(); //NO DEBE LLAMARSE AQUI.

}
};
t
.start();
}

private void updateResultsInUi() {

//update our UI elements based on the data in mResults
[ . . . ]
}

Como comentaba antes, otro modo de comunicación con el handler es mediante el uso de mensajes, que equivale a hacer un "post(Runnable r)":

public class MyActivity extends Activity {

[ . . . ]
// Need handler for callbacks to the UI thread
final Handler mHandler = new Handler(){ @override public void handleMessage(Message msg){ if(msg.what == 0) updateResultsInUi(); } };

// Create runnable for posting
final Runnable mUpdateResults = new Runnable() {
public void run() {
updateResultsInUi
();
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

[ . . . ]
}

protected void startLongRunningOperation() {

// Fire off a thread to do some work that we shouldn't do directly in the UI thread
Thread t = new Thread() {
public void run() {
mResults
= doSomethingExpensive();
//mHandler
.post(mUpdateResults); mHandler.sendMessage(0);
}
};
t
.start();
}
private void updateResultsInUi() {

// Back in the UI thread -- update our UI elements based on the data in mResults
[ . . . ]
}
}

martes, 8 de febrero de 2011

Publicidad y smartphones

La era de la tecnología móvil ya ha comenzado. Las posibilidades para los smartphones empiezan a superar a las de las tecnologías convencionales. Las compañias que sepan aprovechar esta nueva ola digital serán las que consigeran mantenerse.

lunes, 24 de enero de 2011

Spinner en Android

El componente equivalente a un dropdownlist es un Spineer.
Este componente en Android no implementa el onclickItemListener. Obligando a implementar itemSelectedListener. El problema es que el listener asociado salta tanto cuando seleccionamos mediante pantalla un item, como cuando por código queremos seleccionar un elemento de la lista.

Esto supone un problema a la hora de cargar elementos almacenados, pues puede ocurrir que necesitemos:
1º Cargar el spinner con los elementos ->Llama al listener
2º Seleccionar el elemento que de la lista que tenemos guardado -> Llama de nuevo al listener provocando una redundancia.

Para evitar esto, se puede solucionar con una variable booleana que pare los listener mientras se hace la seleccion de los elementos guardados.

martes, 7 de diciembre de 2010