Flujo de trabajo de WebView

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:

  1. Instala Yeoman: https://github.com/yeoman/yeoman/wiki/Getting-Started
  2. 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.

  1. Crea las carpetas src/liveserver y src/staticbuild.

  2. En la carpeta liveserver, crea una carpeta nueva llamada res con una subcarpeta llamada values. Dentro de este, crea un archivo llamado config.xml. Repite este proceso para la carpeta staticbuild.

  3. 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>
    
  4. Configura tu WebView para que use el init_url de estos archivos de configuración.

    mWebView.loadUrl(getString(R.string.init_url));
    
  5. Crea un archivo nuevo llamado AndroidManifest.xml en liveserver/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.

  6. 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 por 0.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:

  1. Inicia el servidor en vivo:

    grunt server
    
  2. 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.