Aplicaciones de WebView para desarrolladores web

Fecha de publicación: 28 de febrero de 2014

Aprende a crear un proyecto de Android nuevo, agregar un WebView, cargar una URL remota y cargar una página HTML local.

En este instructivo, se da por sentado que eres un desarrollador con experiencia limitada o nula en el entorno de desarrollo de Android, pero que tienes cierta experiencia con Kotlin. Si ya conoces la programación para Android, te recomendamos que leas Cómo compilar apps web en WebView en el sitio para desarrolladores de Android.

Instala Android Studio

En este instructivo, se usa Android Studio, el IDE de diseño y compilación para Android.

Crea un nuevo proyecto de Android

Una vez que se instale Android Studio, se iniciará el asistente de configuración.

Para crear un proyecto nuevo, realiza los siguientes pasos:

  1. Haz clic en Nuevo proyecto.
  2. Haz clic en la plantilla Empty Activity para seleccionarla para tu proyecto. Las plantillas crean la estructura del proyecto y los archivos necesarios para que Android Studio compile tu proyecto.
  3. Haz clic en Siguiente para abrir el diálogo Nuevo proyecto.
  4. Configura tu proyecto. Ingresa el nombre de la aplicación, el nombre del paquete y los SDKs de destino. Luego, haz clic en Next.
  5. Establece Minimum required SDK en el nivel de API 24: Android 7.0 (Nougat).
  6. Haz clic en Finalizar.

Android Studio abrirá el proyecto nuevo.

Estructura del proyecto

El proyecto inicial que crea Android Studio tiene código de plantilla para configurar tu aplicación. Estas son algunas de las carpetas de importación más comunes:

  • src/main/java. Código fuente de Java de Android.
  • src/main/res: Son los recursos que usa la aplicación.
  • src/main/res/drawable: Son los recursos de imagen que usa la aplicación.
  • src/main/res/xml: Archivos de diseño XML que definen la estructura de los componentes de la IU.
  • src/main/res/values: Dimensiones, cadenas y otros valores que tal vez no quieras codificar de forma fija en tu aplicación.
  • src/main/AndroidManifest.xml. El archivo de manifiesto define lo que se incluye en la aplicación, como actividades, permisos y temas.

Agrega el WebView

A continuación, agrega un WebView al diseño de la actividad principal.

  1. Abre el archivo activity_main.xml en el directorio src/main/res/xml si aún no está abierto. (Es posible que también veas un archivo fragment_main.xml. Puedes ignorarlo, ya que no es obligatorio para este instructivo.

    Selecciona la pestaña Text en la parte inferior del editor activity_main.xml para ver el marcado XML.

    Este archivo define el diseño de tu actividad principal, y los paneles Preview muestran una vista previa de la actividad. El diseño de Actividad en blanco no incluye ningún elemento secundario. Deberás agregar la WebView.

  2. En el panel XML, quita la barra diagonal de cierre automático del final del elemento FrameLayout y agrega el elemento <WebView> y una nueva etiqueta de cierre, como se muestra a continuación:

    <FrameLayout xmlns:android="https://schemas.android.com/apk/res/android"
        xmlns:tools="https://schemas.android.com/tools"
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
        tools:ignore="MergeRootFrame">
    
        <WebView
          android:id="@+id/activity_main_webview"
          android:layout_width="match_parent"
          android:layout_height="match_parent" />
    </FrameLayout>
    
  3. Para usar WebView, debes hacer referencia a él en la actividad. Abre el archivo fuente de Java para la actividad principal, MainActivity.java, en el directorio src/main/java/<PackageName>.

    Agrega las líneas que se muestran en negrita.

    public class MainActivity extends Activity {
    
        private WebView mWebView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mWebView = (WebView) findViewById(R.id.activity_main_webview);
    

    El código existente en el método onCreate se encarga de conectar la actividad con el diseño. Las líneas agregadas crean una nueva variable de miembro, mWebView, para hacer referencia a la vista web.

    Quita el siguiente código:

    if (savedInstanceState == null) {
      getSupportFragmentManager().beginTransaction()
        .add(R.id.container, new PlaceholderFragment())
        .commit();
    }
    

    El WebView se identifica mediante el ID de recurso, que se especifica en esta línea del archivo de diseño:

    android:id="@+id/activity_main_webview"
    

    Después de agregar el código, verás algunos mensajes de advertencia en el margen del editor. Esto se debe a que no importaste las clases correctas para WebView. Por suerte, Android Studio puede ayudarte a completar las clases faltantes. La forma más fácil de hacerlo es hacer clic en un nombre de clase desconocido y colocar el cursor sobre él, y esperar a que un módulo muestre una "solución rápida"; en este caso, agregar una sentencia import para la clase WebView.

    Presiona Alt + Intro (en Mac, Option + Intro) para aceptar la corrección rápida.

    Con WebView en mano, puedes pasar a configurarlo y cargar contenido web interesante.

Habilitar JavaScript

WebView no permite JavaScript de forma predeterminada. Para ejecutar una aplicación web en WebView, debes habilitar JavaScript de forma explícita. Para ello, agrega las siguientes líneas al método onCreate:

// Enable Javascript
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);

Carga una URL remota

Si vas a cargar datos desde una URL remota, tu aplicación necesita permiso para acceder a Internet. Este permiso se debe agregar en el archivo de manifiesto de la aplicación.

  1. Abre el archivo AndroidManifest.xml en el directorio src/res. Agrega la línea en negrita antes de la etiqueta </manifest> de cierre.

    <?xml version="1.0" encoding="utf-8"?>
    <manifest ...>
    ...
     
      </application>
      <uses-permission android:name="android.permission.INTERNET" />
    </manifest>
    
  2. El siguiente paso es llamar al método loadUrl en el WebView. Agrega la siguiente línea al final del método onCreate.

    mWebView.loadUrl("[https://beta.html5test.com/][8]");
    

    Ahora, intenta ejecutar el proyecto. Si no tienes un dispositivo a mano, puedes crear un emulador (AVD o dispositivo virtual de Android) en Tools > Android > AVD Manager.

Cómo controlar la navegación

Intenta cambiar la URL que cargas a https://www.css-tricks.com/ y vuelve a ejecutar la aplicación. Notarás algo extraño.

Si ejecutas la aplicación ahora con un sitio que tiene un redireccionamiento como css-tricks.com, tu app terminará abriendo el sitio en un navegador del dispositivo, no en tu WebView, lo que probablemente no sea lo que esperabas. Esto se debe a la forma en que WebView controla los eventos de navegación.

Esta es la secuencia de eventos:

  1. WebView intenta cargar la URL original desde el servidor remoto y obtiene un redireccionamiento a una URL nueva.
  2. WebView verifica si el sistema puede controlar un intent de vista para la URL. Si es así, el sistema controla la navegación de la URL; de lo contrario, WebView navega de forma interna (por ejemplo, si el usuario no tiene un navegador instalado en su dispositivo).
  3. El sistema elige la aplicación preferida del usuario para controlar un esquema de URL https://, es decir, el navegador predeterminado del usuario. Si tienes más de un navegador instalado, es posible que veas un diálogo en este punto.

Si usas un WebView dentro de una aplicación para Android para mostrar contenido (por ejemplo, una página de ayuda), es posible que esto sea exactamente lo que deseas hacer. Sin embargo, para aplicaciones más sofisticadas, te recomendamos que administres los vínculos de navegación por tu cuenta.

Para controlar la navegación dentro de WebView, debes anular el WebViewClient de WebView, que controla varios eventos que genera WebView. Puedes usarlo para controlar cómo WebView controla los clics en vínculos y los redireccionamientos de páginas.

La implementación predeterminada de WebViewClient hace que cualquier URL se abra en WebView:

// Force links and redirects to open in the WebView instead of in a browser
mWebView.setWebViewClient(new WebViewClient());

Este es un buen paso adelante, pero ¿qué sucede si solo quieres controlar los vínculos de tu sitio mientras abres otras URLs en un navegador?

Para ello, debes extender la clase WebViewClient e implementar el método shouldOverrideUrlLoading. Se llama a este método cada vez que WebView intenta navegar a una URL diferente. Si muestra un valor falso, WebView abre la URL. (La implementación predeterminada siempre muestra un valor falso, por lo que funciona en el ejemplo anterior).

Crea una clase nueva:

  1. Haz clic con el botón derecho en el nombre del paquete de tu app y selecciona New > Java Class.
  2. Ingresa MyAppWebViewClient como el nombre de la clase y haz clic en Aceptar.
  3. En el nuevo archivo MyAppWebViewClient.java, agrega el siguiente código (los cambios se muestran en negrita):

    public class MyAppWebViewClient extends WebViewClient {
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if(Uri.parse(url).getHost().endsWith("css-tricks.com")) {
          return false;
        }
                   
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        view.getContext().startActivity(intent);
        return true;
      }
    }
    

    El código nuevo define MyAppWebViewClient como una subclase de WebViewClient y, luego, implementa el método shouldOverrideUrlLoading.

    Se llama al método shouldOverrideUrlLoading cada vez que WebView está a punto de cargar una URL. Esta implementación busca la cadena "css-tricks.com" al final del nombre de host de la URL. Si la cadena existe, el método muestra el valor "false", lo que le indica a la plataforma que no anule la URL, sino que la cargue en WebView.

    Para cualquier otro nombre de host, el método envía una solicitud al sistema para que abra la URL. Para ello, crea un nuevo intent de Android y lo usa para iniciar una actividad nueva. Si se muestra el valor true al final del método, se evita que la URL se cargue en WebView.

  4. Para usar tu nuevo WebViewClient personalizado, agrega las siguientes líneas a la clase MainActivity:

    // Stop local links and redirects from opening in browser instead of WebView
    mWebView.setWebViewClient(new MyAppWebViewClient());
    

    Ahora, un usuario puede hacer clic en cualquiera de los vínculos de CSS Tricks y permanecer en la app, pero los vínculos a sitios externos se abren en un navegador.

Cómo controlar el botón Atrás de Android

Cuando comienzas a explorar y navegar por los artículos de CSS Tricks, si haces clic en el botón Atrás en Android, se cierra la aplicación.

El método canGoBack de WebView te indica si hay algo en la pila de páginas que se pueda quitar. Para detectar una presión del botón Atrás y determinar si debes retroceder en el historial de WebView o permitir que la plataforma determine el comportamiento correcto, agrega el método onBackPressed() a tu MainActivity:

public class MainActivity extends Activity {

 private WebView mWebView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
     ...
 }

    @Override
    public void onBackPressed() {
      if(mWebView.canGoBack()) {
        mWebView.goBack();
      } else {
        super.onBackPressed();
      }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
       ...
    }
}

Carga HTML desde el sistema de archivos

Una gran ventaja de usar un WebView dentro de una aplicación instalable es que puedes almacenar recursos dentro de la app. Esto permite que tu app funcione sin conexión y mejora los tiempos de carga, ya que WebView puede recuperar recursos directamente desde el sistema de archivos local.

Para almacenar archivos de forma local, incluidos HTML, JavaScript y CSS, guárdalos en el directorio de recursos. Este es un directorio reservado que Android usa para los archivos sin procesar. Tu app necesita acceso a este directorio, ya que es posible que deba minimizar o comprimir ciertos archivos.

  1. Crea el directorio assets/www en main (src/main/assets/www).

    • Se recomienda mantener los archivos web en un subdirectorio de /assets.
  2. Sube todos los archivos al directorio.

  3. Carga el archivo correspondiente:

    mWebView.loadUrl("file:///android_asset/www/index.html");
    
  4. Actualiza el método shouldOverrideUrlLoading para abrir un navegador para páginas no locales:

    public class MyAppWebViewClient extends WebViewClient {
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if(Uri.parse(url).getHost().length() == 0) {
          return false;
        }
    
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        view.getContext().startActivity(intent);
        return true;
      }
    }
    

Ahora puedes crear una excelente app de WebView.

Para obtener sugerencias sobre cómo obtener las imágenes perfectas, consulta IU de Pixel Perfect en WebView.

Si tienes problemas, las Herramientas para desarrolladores de Chrome son tus aliadas. Consulta Depuración remota en Android para comenzar.