Fecha de publicación: 28 de febrero de 2014
Una de las grandes ventajas del desarrollo web es el amplio conjunto de herramientas que puedes usar para mejorar tu flujo de trabajo.
Un ejemplo de una de estas herramientas es Grunt, un ejecutor de tareas de JavaScript que te permite definir tareas para realizar en tu app web, desde compilar Sass y comenzar un servidor en vivo hasta comprimir imágenes, reducir JavaScript y ejecutar JSHint antes de crear una compilación lista para la producción.
Yeoman es una herramienta que ayuda a crear aplicaciones web, generar un modelo de plantilla, incorporar bibliotecas de Bower y npm, y crear un archivo Grunt con tareas predefinidas.
En este instructivo, usarás Yeoman para crear una nueva aplicación web básica y, luego, integrarás el sistema de compilación de Android Studio (Gradle) con Grunt para compilar tu aplicación web. También configurarás tareas de Grunt para iniciar un servidor de recarga en vivo local para probar tu aplicación en el navegador, de modo que no tengas que actualizar la página de forma manual cada vez que cambies un archivo HTML, CSS o JavaScript.
Requisitos previos
Antes de comenzar, deberás instalar algunos requisitos previos:
- Instala Yeoman: https://github.com/yeoman/yeoman/wiki/Getting-Started
- Instala Android Studio: https://developer.android.com/sdk/installing/studio.html
Paso 1: Crea un proyecto nuevo en Android Studio con un WebView
Puedes encontrar instrucciones completas para hacerlo en la guía de introducción.
Paso 2: Crea un subdirectorio para el contenido de la app web
Después de crear tu proyecto, crea un nuevo directorio de nivel superior. En Android Studio, haz clic con el botón derecho en la carpeta del proyecto y selecciona New > Directory.
Asígnale un nombre al directorio webapp
.
Paso 3: Crea un proyecto de Yeoman en tu directorio nuevo
En una terminal, cd
al directorio webapp
en el proyecto.
cd <path-to-project>/webapp/
Luego, crea una nueva app web con Yeoman:
yo webapp
Sigue las instrucciones en pantalla para seleccionar las opciones del proyecto. Es posible que debas ejecutar sudo npm install
, según cómo esté instalado npm en tu máquina.
Antes de continuar con el siguiente paso, ejecuta el siguiente comando para probar la app:
grunt server
Se debería abrir una pestaña nueva en tu navegador, que se conectará a un servidor local que inició Grunt. Si cambias uno de los archivos HTML, CSS o JavaScript del proyecto, la página se vuelve a cargar y actualizar automáticamente.
Si ejecutas grunt build
, se crea un directorio nuevo, dist
, y tu app web se comprime, se optimiza y se convierte en una versión lista para producción dentro de esta carpeta.
Paso 4: Configura la compilación de Gradle
En el directorio webapp
, crea un archivo nuevo llamado build.gradle
.
En tu nuevo archivo build.gradle
, agrega lo siguiente:
import org.apache.tools.ant.taskdefs.condition.Os
task buildWebApp(type: Exec) {
executable = Os.isFamily(Os.FAMILY_WINDOWS) ? "grunt.cmd" : "grunt"
args = ["build"]
}
Esto crea una tarea nueva llamada buildWebApp
con un tipo predefinido Exec
.
Luego, establece la variable executable
en Exec
en el comando grunt correspondiente según el SO actual. args
se establece en "build"
, lo que equivale a que grunt build
se ejecute en la línea de comandos. Por último, la importación en la parte superior es para usar Os.isFamily(Os.FAMILY_WINDOWS)
.
Antes de poder usar esta nueva tarea, debemos informarle al proyecto sobre el nuevo archivo build.gradle
.
Abre settings.gradle
en el directorio raíz y agrega la siguiente línea:
include ':webapp'
Paso 5: Compila tu app web cuando compiles la app para Android
Haz que se compile la app web y, luego, cópiala en el directorio assets
de nuestra app para Android.
Copia lo siguiente en el archivo build.gradle
de la app para Android:
task copyWebApplication(type: Copy) {
from '../webapp/dist'
into 'src/main/assets/www'
}
task deleteWebApplication(type: Delete) {
delete 'src/main/assets/www'
}
copyWebApplication.dependsOn ':webapp:buildWebApp'
copyWebApplication.dependsOn deleteWebApplication
android.applicationVariants.all { variant ->
tasks.getByPath(":${project.name}:assemble${variant.buildType.name.capitalize()}").dependsOn copyWebApplication
}
Analicemos cada parte.
tarea copyWebApplication
task copyWebApplication(type: Copy) {
from '../webapp/dist'
into 'src/main/assets/www'
}
Esta tarea de Copy
copia tu aplicación del directorio webapp/dist
. Queremos copiar los archivos a src/main/assets/www
. Esta tarea también crea la estructura de archivos necesaria si no existe ninguno de los directorios requeridos.
tarea deleteWebApplication
task deleteWebApplication(type: Delete) {
delete 'src/main/assets/www'
}
Esta tarea de eliminación borra todos los archivos del directorio assets/www
.
copyWebApplication.dependsOn
copyWebApplication.dependsOn ':webapp:buildWebApp'
copyWebApplication.dependsOn deleteWebApplication
La primera línea de este archivo indica que copyWebApplication
tiene una dependencia en la tarea buildWebApp
del archivo build.gradle
de nuestra app web.
La segunda línea indica que hay una dependencia en la tarea deleteWebApplication
.
En otras palabras, antes de copiar archivos en el directorio assets
, asegúrate de compilar la app web y borrar el contenido actual del directorio assets
.
android.applicationVariants.all
android.applicationVariants.all { variant ->
tasks.getByPath(":${project.name}:assemble${variant.buildType.name.capitalize()}").dependsOn copyWebApplication
}
Esta tarea especifica las dependencias de todas las compilaciones de tu proyecto, para cada versión de tu app. Aquí, se establece una dependencia en las tareas assemble
para ejecutar copyWebApplication
.
Las tareas de assemble
ensamblan el resultado del proyecto, por lo que primero se debe copiar la app web en el proyecto de Android.
Paso 6: Asegúrate de que todo funcione
En Android Studio, no deberías tener ningún directorio assets
en la carpeta src
de tus aplicaciones para Android.
Configura WebView para que use la página index.html
:
mWebView.loadUrl("file:///android_asset/www/index.html");
Haz clic en Run y deja que se compile la aplicación. Deberías ver un directorio assets
con tu aplicación web en el subdirectorio www
.
Paso 7: Crea un servidor en vivo y una actualización en vivo
La recarga en vivo puede ser muy útil para realizar cambios rápidos en tus aplicaciones web. Para habilitar esto, puedes crear dos "variantes de producto" para tu app: una versión del servidor publicada y una versión estática, en la que el contenido web se empaqueta en la aplicación para Android.
En el archivo build.gradle
de tu app para Android, agrega las siguientes líneas al final
del elemento android
:
android {
...
defaultConfig {
...
}
productFlavors {
staticbuild {
packageName "com.google.chrome.myapplication"
}
liveserver {
packageName "com.google.chrome.myapplication.liveserver"
}
}
}
Gradle ahora te ofrece la posibilidad de crear una versión de tu app con un nombre de paquete de servidor en vivo y una con tu nombre de paquete normal. Para verificar si funcionó, haz clic en Sync Project with Gradle Files (en la barra superior junto al botón Run).
Luego, consulta las Build Variants que se encuentran en la esquina inferior izquierda de Android Studio, que básicamente te muestran las versiones de tu app que puedes compilar.
Para cada productFlavor
, hay versiones Debug y Release, que el complemento de Android para Gradle te proporciona de forma predeterminada. Esto determina si la compilación debe ser una compilación de depuración o una compilación de lanzamiento adecuada para implementarse en Play Store.
Ahora tienes dos versiones, pero aún no hacen nada diferente.
Paso 8: Carga desde un servidor en vivo
Ahora, configura tu aplicación para que cargue una URL diferente según la variante de producto que compiles.
En tu aplicación para Android, los archivos comunes a todas las variantes de productos se encuentran en src/main
. Para agregar código o recursos específicos de una variante de producto, crea otro directorio en src
con el mismo nombre que tu productFlavor
. Cuando compilas para esa variante de compilación, Gradle y el complemento de Android combinan estos archivos adicionales con los archivos de src/main
.
Define la URL como un recurso de cadena y úsalo en tu código en lugar de una URL hard-coded.
Crea las carpetas
src/liveserver
ysrc/staticbuild
.En la carpeta
liveserver
, crea una carpeta nueva llamadares
con una subcarpeta llamadavalues
. Dentro de este, crea un archivo llamadoconfig.xml
. Repite este proceso para la carpetastaticbuild
.Dentro de tus archivos de configuración, agrega las siguientes líneas a
src/liveserver/res/values/config.xml
:<?xml version="1.0" encoding="utf-8"?> <resources> <string name="init_url">https://<Your Local Machine IP Address>:9000</string> </resources>
Agrega el siguiente bloque a
src/staticbuild/res/values/config.xml
:<?xml version="1.0" encoding="utf-8"?> <resources> <string name="init_url">file:///android_asset/www/index.html</string> </resources>
Configura tu WebView para que use el
init_url
de estos archivos de configuración.mWebView.loadUrl(getString(R.string.init_url));
Crea un archivo nuevo llamado
AndroidManifest.xml
enliveserver/AndroidManifest.xml
y agrega las siguientes líneas:<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="https://schemas.android.com/apk/res/android"> <uses-permission android:name="android.permission.INTERNET" /> </manifest>
Esto agrega el permiso de Internet para las compilaciones de
liveserver
.Dentro de
webapp/Gruntfile.js
, busca lo siguiente:connect: { options: { port: 9000, livereload: 35729, // change this to '0.0.0.0' to access the server from outside hostname: **'localhost'** }, ... }
Reemplaza
localhost
por0.0.0.0
para que se pueda acceder a tu servidor local desde la red local:connect: { options: { port: 9000, livereload: 35729, // change this to '0.0.0.0' to access the server from outside hostname: '**0.0.0.0'** }, ... }
Para probar tus cambios, sigue estos pasos:
Inicia el servidor en vivo:
grunt server
En Android Studio, en la selección Build Variant, selecciona LiveserverDebug. Luego, haz clic en Ejecutar.
Deberías poder editar tu contenido HTML, CSS y JavaScript, y verlo reflejado de inmediato en el navegador.
Ahora tienes dos versiones de tu aplicación: una versión de desarrollo con una carga en vivo desde el servidor de Grunt y una versión estática, empaquetada de forma local en la app para Android.