Creo que esto puede ser interesante para muchos, lo pego directamente:
Hace poco en Codenix nos compramos un iPhone 2 y un Galaxy Tab para explorar un poco las plataformas, dada la alta y creciente demanda que hay, y el hecho de que clientes estan interesados en hacer cosas para las mismas.
Dada la cantidad enorme de codigo en C++ que tenemos, y que C++ es practicamente el unico lenguaje que permite escribir codigo para todas las plataformas (excepto web, salvo por nativeclient), me puse en campaña para portar nuestro engine (don godofredo). Como estoy con mucho laburo, lo fui haciendo de a pedacitos cuando tuve tiempo.
Dado que la mayoria conocen iPhone, me voy a enfocar en mi experiencia con Android..
Nota al margen, no pidan mucha ayuda en foros o en irc.. yo no se que le pasa por la cabeza a la gente pero asi como la mayoria de quienes programan para iPhone dicen que lo mejor para programar es Objective C, en Android la mayoria te van a decir que es al pedo usar C++ y que Java es mejor, y que usar NDK es "dirty" y no es la forma correcta de programar para Android.
Explicarle a alguien que si vas a hacer una inversion en tecnologia, y que desarrollas para clientes que publican en PC, Mac, telefonos y consolas, y obviamente vas a obviar el lenguaje nativo por mas bueno que este para elegir un lenguaje que funcione en todas las plataformas.. es inutil.
El primer intento fue hacerlo en Java+JNI, ya que parece ser lo mas comun. Esto consiste en hacer un "core" minimo de la aplicacion en Java que se comunica con el codigo en C++, que es cargado de un shared object. Este approach es similar al que hace mucho se usaba en PalmOS 5 para comunicar el codigo de m68k con el de ARM, y la verdad es que es bastante hinchapelotas. Para la parte de C++ esta el Android NDK, que se agrega al SDK y trae gcc, headers, etc para hacer la compilacion nativa. Si bien se puede, lo unico que realmente ganas es que tu aplicacion funcione en android 2.1 y 2.2.
Como mi objetivo en este momento es que funcione, y no vender nada (Todavia), y prefiero tener algo funcionando antes que pelearme con Java+JNI, decidi programar para NativeActivity, un framework nativo de C/C++que tiene practicamente toda la API relevante de Android en headers. La limitacion es que solamente funciona en telefonos con Android 2.3+, y son muy poquitos los telefonos que se venden con esa version en este momento. Bueno, supongo que cuando necesite vender algo, me esforzare un poco mas en terminar la version de JNI.
Respecto a las herramientas, hay dos opciones:
1) Haces todo comodamente desde la IDE Eclipse
2) Estas en bolas, arreglatelas como puedas
En mi caso elegi 2), porque:
a) El engine es enorme y usa un sistema de build complejo que genera un monton de archivos, maneja varias plataformas, etc. Adaptarlo al sistema pedorro de makefiles de Android/Eclipse es mas dificil que adaptar los buid-steps de Android a SCons.
b) No me gusta eclipse..
En general no fue muy dificil tener mi proyecto compilando para Android, no me llevo mas de 2 o 3 horas. Las herramientas de commandline (android y adb) son excelentes y muy intuitivas, y permiten controlar todo lo que pasa en el telefono con un par de comanditos. Ej, poner o sacar archivos, instalar cosas, ejecutar un shell remoto, ver los logs, etc. Muy util!
El problema surgio cuando, obviamente, al correr lo que hice por primera vez se colgo todo a la re [xxxx].. entonces me puse a ver como usar gdb y ahi es cuando empezaron a surgir los problemas. Para debuggear aplicaciones, hay que usar gdbserver en el telefono, y comunicarlo por un pipe shareado a traves de usb a un gdb local. Al mismo tiempo, para debugear, hay que transferir el espacio virtual del proceso al host (a la PC) para que gdb local lea el codigo y demas. Si eso ya suena complicado, hacerlo es 50 veces mas complicado.
Android es un sistema operativo basado en linux donde cada aplicacion es un usuario, de esta forma pueden muy facilmente darle un espacio virtual y limitaciones a cada aplicaccion, para que no interactue con el resto del sistema operativo. El problema es que este sandbox no permite conectar gdbserver al proceso facilmente, ya que hay que correrlo con el usuario correcto para que pueda engancharse. Para solucionarlo, hay que meter gdbserver dentro de la aplicacion, asi corre con iguales permisos y despues pedirle a adb que ejecute comandos como si fuera el usuario.
La verdad, es muy complejo y no logre hacerlo andar. Android NDK viene con un script que lo hace por vos (ndk-gdb), pero esta extremadamente mal programado y siempre falla por una boludez u otra. Me canse de atarlo con alambre y finalmente recurri a printf para arreglar los crashes.
Google definitivamente tiene que mejorar Android en ese aspecto..
Respecto al telefono y a la API en si, la API en general esta bien, pero tiene varias estupideces, especialmente en lo siguiente:
1) El contexto de OpenGL se borra cada vez que suspendes y volves de la aplicacion. Si bien te avisa, esto es una reverenda mierda. en la documentacion dice "usa este callback para subir los recursos de vuelta". Obviamente quien hizo la API jamas programo un juego en su vida y jamas se le paso por la cabeza que mucho del contenido puede estar generado o modificado en tiempo de ejcucion. (Ej: texturas generadas, esqueletos, particulas por GLSL, etc). La solucion es, lamentablemente, mantener copia de los recursos cargados en RAM, como hacen las versiones mas viejas de DirectX en Windows XP. Es un desperdicio de memoria, pero bueh..
Simplemente una idea estupida que sacrifica la calidad de las aplicaciones y dificulta enormemente el porting. Creo que es mejor que Android mate mas aplicaciones porque se quedo sin memoria a que te incremente tanto la complejidad.
2) No poes acceder al filesystem, todo tu contenido se guarda en el APK (Android Package) y se accede con una API de Google, (AssetManager). La API simula un filesystem, pero es *MUY* sencilla y limitada. Las trasnferencias del APK a memoria son lentas, y el toolchain de Android se le puede cantar comprimirte todo, sin preguntarte si asi lo desea, enlentenciendo aun mas la carga. En los foros dice que renombes tus archivos, sean lo que sean, a mp3 para que el tool no los comprima. De la misma forma, Android puede decidir subir algunos assets a memoria POR QUE SI. Podes preguntar si estan en memoria, pero que se yo.. es complicado el tema... y hay que arreglarlo metiendo buffering.
3) La documentacion de la API nativa no existe. No es exactamente la misma que la API de Java asi que hay que ir con sombrero de Indiana Jhones y probar..
Pero bueno, fuera de esos problemas, es bastante trabajable y las herramientas de commandline facilitan mucho la tarea de subir versiones nuevas y probar.. cuando tenga tiempo de hacer mas y haya mas progreso vuelvo a postear, saludos!!