From 65e62f4f908394fc469cf535fef7c16035a428a2 Mon Sep 17 00:00:00 2001 From: Scott Main Date: Mon, 20 Sep 2010 12:46:34 -0700 Subject: docs: new web apps dev guides Change-Id: I08b80de0544fec5d46a58e1c1b4c0e2ff1fd4fa2 --- docs/html/guide/webapps/best-practices.jd | 90 +++++++ docs/html/guide/webapps/debugging.jd | 158 +++++++++++ docs/html/guide/webapps/targetting.jd | 419 ++++++++++++++++++++++++++++++ docs/html/guide/webapps/webview.jd | 328 +++++++++++++++++++++++ 4 files changed, 995 insertions(+) create mode 100644 docs/html/guide/webapps/best-practices.jd create mode 100644 docs/html/guide/webapps/debugging.jd create mode 100644 docs/html/guide/webapps/targetting.jd create mode 100644 docs/html/guide/webapps/webview.jd (limited to 'docs/html/guide/webapps') diff --git a/docs/html/guide/webapps/best-practices.jd b/docs/html/guide/webapps/best-practices.jd new file mode 100644 index 0000000..1bde5bf --- /dev/null +++ b/docs/html/guide/webapps/best-practices.jd @@ -0,0 +1,90 @@ +page.title=Best Practices for Web Apps +@jd:body + + + +

Developing web pages and web applications for mobile devices presents a different set of +challenges compared to developing a web page for the typical +desktop web browser. To help you get started, the following is a list of practices you should +follow in order to provide the most effective web application for Android and other mobile +devices.

+ +
    + +
  1. Redirect mobile devices to a dedicated mobile version of your web site +

    There are several ways you can redirect requests to the mobile version of your web site, using +server-side redirects. Most often, this is done by "sniffing" the User Agent +string provided by the web browser. To determine whether to serve a mobile version of your site, you +should simply look for the "mobile" string in the User Agent, which matches a wide variety of mobile +devices. If necessary, you can also identify the specific operating system in the User Agent string +(such as "Android 2.1").

    +
  2. + + +
  3. Use a valid markup DOCTYPE that's appropriate for mobile devices +

    The most common markup language used for mobile web sites is XHTML Basic. This standard +ensures specific markup for your web site that works best on mobile devices. For instance, it does +not allow HTML frames or nested tables, which perform poorly on mobile devices. Along with the +DOCTYPE, be sure to declare the appropriate character encoding for the document (such as +UTF-8).

    +

    For example:

    +
    +<?xml version="1.0" encoding="UTF-8"?>
    +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"
    +    "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">
    +
    + +

    Also be sure that your web page markup is valid against the declared DOCTYPE. Use a +validator, such as the one available at +http://validator.w3.org.

    +
  4. + + +
  5. Use viewport meta data to properly resize your web page +

    In your document {@code <head>}, you should provide meta data that specifies how you +want the browser's viewport to render your web page. For example, your viewport meta data can +specify the height and width for the browser's viewport, the initial web page scale and even the +target screen density.

    +

    For example:

    +
    +<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    +
    +

    For more information about how to use viewport meta data for Android-powered devices, read Targetting Android Devices.

    +
  6. + + +
  7. Avoid multiple file requests +

    Because mobile devices typically have a connection speed far slower than a desktop +computer, you should make your web pages load as fast as possible. One way to speed it up is to +avoid loading extra files such as stylesheets and script files in the {@code +<head>}. Instead, provide your CSS and JavaScript directly in the <head> (or +at the end of the <body>, for scripts that you don't need until the page is loaded). +Alternatively, you should optimize the size and speed of your files by compressing them with tools +like Minify.

    +
  8. + + +
  9. Use a vertical linear layout +

    Avoid the need for the user to scroll left and right while navigating your web +page. Scrolling up and down is easier for the user and makes your web page simpler.

    +
  10. + +
+ +

For a more thorough guide to creating great mobile web applications, see the W3C's Mobile Web Best Practices. For other guidance on +improving the speed of your web site (for mobile and desktop), see Yahoo!'s guide to Exceptional Performance and +Google's speed tutorials in Let's make the web +faster.

+ + diff --git a/docs/html/guide/webapps/debugging.jd b/docs/html/guide/webapps/debugging.jd new file mode 100644 index 0000000..098e17c --- /dev/null +++ b/docs/html/guide/webapps/debugging.jd @@ -0,0 +1,158 @@ +page.title=Debugging Web Apps +@jd:body + +
+
+

Quickview

+
    +
  • You can debug your web app using console methods in JavaScript
  • +
  • If debugging in a custom WebView, you need to implement a callback method to handle debug +messages
  • +
+ +

In this document

+
    +
  1. Using Console APIs in the Android Browser
  2. +
  3. Using Console APIs in WebView
  4. +
+ +

See also

+
    +
  1. Debugging Tasks
  2. +
+ +
+
+ +

If you're developing a web application for Android, you can debug your JavaScript +using the {@code console} JavaScript APIs, which output messages to logcat. If you're familiar with +debugging web pages with Firebug or Web Inspector, then you're probably familiar +with using {@code console} (such as {@code console.log()}). Android's WebKit framework supports most +of the same APIs, so you can receive logs from your web page when debugging in Android's Browser +or in your own {@link android.webkit.WebView}.

+ + + +

Using Console APIs in the Android Browser

+ + + +

When you call a {@code console} function (in the DOM's {@code window.console} object), +the output appears in logcat. For example, if your web page executes the following +JavaScript:

+
+console.log("Hello World");
+
+

Then the logcat message looks something like this:

+
+Console: Hello World http://www.example.com/hello.html :82
+
+ +

The format of the message might appear different depending on which version of Android you're +using. On Android 2.1 and higher, console messages from the Android Browser +are tagged with the name "browser". On Android 1.6 and lower, Android Browser +messages are tagged with the name "WebCore".

+ +

Android's WebKit does not implement all of the console APIs available in other desktop browsers. +You can, however, use the basic text logging functions:

+ + +

Other console functions don't raise errors, but might not behave the same as what you +expect from other web browsers.

+ + + +

Using Console APIs in WebView

+ +

If you've implemented a custom {@link android.webkit.WebView} in your application, all the +same console APIs are supported when debugging your web page in WebView. On Android +1.6 and lower, console messages are automatically sent to logcat with the +"WebCore" logging tag. If you're targetting Android 2.1 (API Level 7) or higher, then you must +provide a {@link android.webkit.WebChromeClient} +that implements the {@link android.webkit.WebChromeClient#onConsoleMessage(String,int,String) +onConsoleMessage()} callback method, in order for console messages to appear in logcat.

+ +

Additionally, the {@link +android.webkit.WebChromeClient#onConsoleMessage(String,int,String)} method introduced in API +Level 7 has been deprecated in favor of {@link +android.webkit.WebChromeClient#onConsoleMessage(ConsoleMessage)} in API Level 8.

+ +

Whether you're developing for Android 2.1 (API Level 7) or Android 2.2 (API Level 8 or +greater), you must implement {@link android.webkit.WebChromeClient} and override the appropriate +{@link +android.webkit.WebChromeClient#onConsoleMessage(String,int,String) onConsoleMessage()} callback +method. Then, apply the {@link android.webkit.WebChromeClient} to your {@link +android.webkit.WebView} with {@link android.webkit.WebView#setWebChromeClient(WebChromeClient) +setWebChromeClient()}. + +

Using API Level 7, this is how your code for {@link +android.webkit.WebChromeClient#onConsoleMessage(String,int,String)} might look:

+ +
+WebView myWebView = (WebView) findViewById(R.id.webview);
+myWebView.setWebChromeClient(new WebChromeClient() {
+  public void onConsoleMessage(String message, int lineNumber, String sourceID) {
+    Log.d("MyApplication", message + " -- From line "
+                         + lineNumber + " of "
+                         + sourceID);
+  }
+});
+
+ +

With API Level 8 or greater, your code for {@link +android.webkit.WebChromeClient#onConsoleMessage(ConsoleMessage)} might look like this:

+ +
+WebView myWebView = (WebView) findViewById(R.id.webview);
+myWebView.setWebChromeClient(new WebChromeClient() {
+  public boolean onConsoleMessage(ConsoleMessage cm) {
+    Log.d("MyApplication", cm.{@link android.webkit.ConsoleMessage#message()} + " -- From line "
+                         + cm.{@link android.webkit.ConsoleMessage#lineNumber()} + " of "
+                         + cm.{@link android.webkit.ConsoleMessage#sourceId()} );
+    return true;
+  }
+});
+
+ +

The {@link android.webkit.ConsoleMessage} also includes a {@link +android.webkit.ConsoleMessage.MessageLevel MessageLevel} to indicate the type of console message +being delivered. You can query the message level with {@link +android.webkit.ConsoleMessage#messageLevel()} to determine the severity of the message, then +use the appropriate {@link android.util.Log} method or take other appropriate actions.

+ +

Whether you're using {@link +android.webkit.WebChromeClient#onConsoleMessage(String,int,String)} or {@link +android.webkit.WebChromeClient#onConsoleMessage(ConsoleMessage)}, when you execute a console method +in your web page, Android calls the appropriate {@link +android.webkit.WebChromeClient#onConsoleMessage(String,int,String) +onConsoleMessage()} method so you can report the error. For example, with the example code above, +a logcat message is printed that looks like this:

+ +
+Hello World -- From line 82 of http://www.example.com/hello.html
+
+ + + + + + diff --git a/docs/html/guide/webapps/targetting.jd b/docs/html/guide/webapps/targetting.jd new file mode 100644 index 0000000..844b9ca --- /dev/null +++ b/docs/html/guide/webapps/targetting.jd @@ -0,0 +1,419 @@ +page.title=Targetting Android Devices +@jd:body + +
+
+

Quickview

+
    +
  • You can target your web page for different screens using viewport metadata, CSS, and +JavaScript
  • +
  • Techniques in this document work for Android 2.0 and greater
  • +
+ +

In this document

+
    +
  1. Using Viewport Metadata +
      +
    1. Defining the viewport size
    2. +
    3. Defining the viewport scale
    4. +
    5. Defining the viewport target density
    6. +
    +
  2. +
  3. Targetting Device Density with CSS
  4. +
  5. Targetting Device Density with JavaScript
  6. +
+ +
+
+ + +

If you're developing a web application for Android or redesigning one for mobile devices, you +should account for some factors that affect the way the Android Browser renders your web page by +default. There are two fundamental factors that you should account for:

+ +
+
The size of the viewport and scale of the web page
+
When the Android Browser loads a web page, the default behavior is to load the +page in "overview mode," which provides a zoomed-out perspective of the web page. You can override +this behavior for your web page by defining the default dimensions of the viewport or the initial +scale of the viewport. You can also control how much the user can zoom in and out of your web +page, if at all. +

However, the user can also disable overview mode in the +Browser settings, so you should not assume that your page will load in overview mode. You +should instead customize the viewport size and/or scale as appropriate for your page.

+ +
The device's screen density
+
The screen density (the number of pixels per inch) on an Android-powered device affects +the resolution and size at which a web page is displayed. (There are three screen density +categories: low, medium, and high.) The Android Browser compensates for variations in the screen +density by scaling a web page so that all devices display the web page at the same perceivable size +as a medium-density screen. If graphics are an important element of your web design, you +should pay close attention to the scaling that occurs on different densities, because image scaling +can produce artifacts (blurring and pixelation). +

To provide the best visual representation on all +screen densities, you should control how scaling occurs by providing viewport metadata about +your web page's target screen density and providing alternative graphics for different screen +densities, which you can apply to different screens using CSS or JavaScript.

+
+ +

The rest of this document describes how you can account for these effects, and how to target +your web page for specific screen configurations.

+ +

Note: The features described in this document are supported +by the Android Browser application on Android 2.0 and greater. Third-party web browsers running on +Android might not support these techniques for controlling the viewport size and targetting +screen densities.

+ + + +

Using Viewport Metadata

+ +

The viewport is the area in which the Android Browser +draws a web page. Although the viewport's visible area matches the size of the screen, +the viewport has its own dimensions that determine the number of pixels available to a web page. +That is, the number of pixels available to a web page before it exceeds the screen area is +defined by the dimensions of the viewport, +not the dimensions of the device screen. For example, although a device screen might have a width of +480 pixels, the viewport can have a width of 800 pixels, so that a web page designed to be 800 +pixels wide is completely visible on the screen.

+ +

You can define properties of the viewport for your web page using the {@code "viewport"} +property in an HTML {@code <meta>} tag (which must +be placed in your document {@code <head>}). You can define multiple viewport properties in the +{@code <meta>} tag's {@code content} attribute. For example, you can define the height and +width of the viewport, the initial scale of the page, and the target screen density. +Each viewport property in the {@code content} attribute must be separated by a comma.

+ +

For example, the following snippet from an HTML document specifies that the viewport width +should exactly match the device screen width and that the ability to zoom should be disabled:

+ +
+<head>
+    <title>Example</title>
+    <meta name="viewport" content="width=device-width, user-scalable=no" />
+</head>
+
+ +

That's an example of just two viewport properties. The following syntax shows all of the +supported viewport properties and the general types of values accepted by each one:

+ +
+<meta name="viewport"
+      content="
+          height = [pixel_value | device-height] ,
+          width = [pixel_value | device-width ] ,
+          initial-scale = float_value ,
+          minimum-scale = float_value ,
+          maximum-scale = float_value ,
+          user-scalable = [yes | no] ,
+          target-densitydpi = [dpi_value | device-dpi |
+                               high-dpi | medium-dpi | low-dpi]
+          " />
+
+ +

The following sections discuss how to use each of these viewport properties and exactly what the +accepted values are.

+ +
+ +

Figure 1. A web page with no viewport metadata and an +image that's 320 pixels wide (the viewport is 800 pixels wide, by default).

+
+ + +
+ +

Figure 2. A web page with viewport {@code width=400} +(the image in the web page is 320 pixels wide).

+
+ + +

Defining the viewport size

+ +

Viewport's {@code height} and {@code width} properties allow you to specify the size of the +viewport (the number of pixels available to the web page before it goes off screen). By default, the +Android Browser's minimum viewport width is 800 pixels, so if your web +page specifies its size to be 320 pixels wide, then your page renders smaller than the visible +screen (even if the physical screen is 320 pixels wide, because the viewport simulates a +drawable area that's 800 pixels wide), as shown in figure 1. So, you should explicitly define the +viewport {@code width} to match the width for which you have designed your web page.

+ +

Note: Width values that are greater than 10,000 are ignored and +values less than (or equal to) 320 result in a value equal to the device-width. Height values that +are greater then 10,000 or less than 200 are also ignored.

+ +

For example, if your web page is designed to be exactly 320 pixels wide, then you might +want to specify that for the viewport width:

+ +
+<meta name="viewport" content="width=320" />
+
+ +

In this case, your web page exactly fits the screen width, because the web page width and +viewport width are the same.

+ +

To demonstrate how this property affects the size of +your web page, figure 2 shows a web page that contains an image that's 320 pixels wide, but with the +viewport width set to 400.

+ + +

Note: If you set the viewport width to match your web page width +and the device screen width does not match those dimensions, then the web page +still fits the screen even if the device has a high or low-density screen, because the +Android Browser scales web pages to match the perceived size on a medium-density +screen, by default (as you can see in figure 2, when comparing the hdpi device to the mdpi device). +Screen densities are discussed more in Defining the viewport target +density.

+ + +

Automatic sizing

+ +

As an alternative to specifying the viewport dimensions with exact pixels, you can set the +viewport size to always match the dimensions of the device screen, by defining the +viewport properties {@code height} +and {@code width} with the values {@code device-height} and {@code device-width}, respectively. This +is appropriate when you're developing a web application that has a fluid width (not fixed width), +but you want it to appear as if it's fixed (to perfectly fit every screen as +if the web page width is set to match each screen). For example:

+ +
+<meta name="viewport" content="width=device-width" />
+
+ +

This results in the viewport width matching whatever the current screen width is, as shown in +figure 3. It's important to notice that, this results in images being scaled to fit the screen +when the current device does not match the target +density, which is medium-density if you don't specify otherwise. As a result, the image +displayed on the high-density device in figure 3 is scaled up in order to match the width +of a screen with a medium-density screen.

+ +
+ +

Figure 3. A web page with viewport {@code +width=device-width} or {@code initial-scale=1.0}.

+
+ +

Note: If you instead want {@code +device-width} and {@code device-height} to match the physical screen pixels for every device, +instead of scaling your web page to match the target density, then you must also include +the {@code target-densitydpi} property with a value of {@code device-dpi}. This is discussed more in +the section about Defining the viewport density. Otherwise, simply +using {@code device-height} and {@code device-width} to define the viewport size makes your web page +fit every device screen, but scaling occurs on your images in order to adjust for different screen +densities.

+ + + +

Defining the viewport scale

+ +

The scale of the viewport defines the level of zoom applied to the web page. Viewport +properties allow you to specify the scale of your web page in the following ways:

+
+
{@code initial-scale}
+
The initial scale of the page. The value is a float that indicates a multiplier for your web +page size, relative to the screen size. For example, if you set the initial scale to "1.0" then the +web page is displayed to match the resolution of the target +density 1-to-1. If set to "2.0", then the page is enlarged (zoomed in) by a factor of 2. +

The default initial scale is calculated to fit the web page in the viewport size. +Because the default viewport width is 800 pixels, if the device screen resolution is less than +800 pixels wide, the initial scale is something less than 1.0, by default, in order to fit the +800-pixel-wide page on the screen.

+ +
{@code minimum-scale}
+
The minimum scale to allow. The value is a float that indicates the minimum multiplier for +your web page size, relative to the screen size. For example, if you set this to "1.0", then the +page can't zoom out because the minimum size is 1-to-1 with the target +density.
+ +
{@code maximum-scale}
+
The maximum scale to allow for the page. The value is a float that indicates the +maximum multiplier for your web page size, +relative to the screen size. For example, if you set this to "2.0", then the page can't +zoom in more than 2 times the target size.
+ +
{@code user-scalable}
+
Whether the user can change the scale of the page at all (zoom in and out). Set to {@code yes} +to allow scaling and {@code no} to disallow scaling. The default is {@code yes}. If you set +this to {@code no}, then the {@code minimum-scale} and {@code maximum-scale} are ignored, +because scaling is not possible.
+
+ +

All scale values must be within the range 0.01–10.

+ +

For example:

+ +
+<meta name="viewport" content="initial-scale=1.0" />
+
+ +

This metadata sets the initial scale to be full sized, relative to the viewport's target +density.

+ + + + +

Defining the viewport target density

+ +

The density of a device's screen is based on the screen resolution. There are three screen +density categories supported by Android: low (ldpi), medium (mdpi), and high (mdpi). A screen +with low density has fewer available pixels per inch, whereas a screen with high density has more +pixels per inch (compared to a medium density screen). The Android Browser targets a medium density +screen by default.

+ + +
+ +

Figure 4. A web page with viewport {@code +width=device-width} and {@code target-densitydpi=device-dpi}.

+
+ + +

Because the default target density is medium, when users have a device with a low or high density +screen, the Android Browser scales web pages (effectively zooms the pages) so they display at a +size that matches the perceived appearance on a medium density screen. Specifically, the Android +Browser applies approximately 1.5x scaling to web pages on a high density screen +(because its screen pixels are smaller) and approximately 0.75x scaling to pages on a low density +screen (because its screen pixels are bigger).

+ +

Due to this default scaling, figures 1, 2, and 3 show the example web page at the same physical +size on both the high and medium density device (the high-density device shows the +web page with a default scale factor that is 1.5 times larger than the actual pixel resolution, to +match the target density). This can introduce some undesirable artifacts in your images. +For example, although an image appears the same size on a medium and high-density device, the image +on the high-density device appears more blurry, because the image is designed to be 320 pixels +wide, but is drawn with 480 pixels.

+ +

You can change the target screen density for your web page using the {@code target-densitydpi} +viewport property. It accepts the following values:

+ +

+ +

For example, to prevent the Android Browser from scaling of your web page for different screen +densities, set +the {@code target-densitydpi} viewport property to {@code device-dpi}. When you do, the Android +Browser does not scale the page and, instead, displays your web page to match the current screen +density. In this case, you should also define the viewport width to match the device width, so your +web page naturally fits the screen size. For example:

+ +
+<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" />
+
+ +

Figure 4 shows a web page using these viewport settings—the high-density device +now displays the page smaller because its physical pixels are smaller than those on the +medium-density device, so no scaling occurs and the 320-pixel-wide image is drawn using exactly 320 +pixels on both screens. (This is how you should define your viewport if +you want to customize your web page based on screen density and provide different image assets for +different densities, with CSS or +with JavaScript.)

+ + +

Targetting Device Density with CSS

+ +

The Android Browser supports a CSS media feature that allows you to create styles for specific +screen densities—the -webkit-device-pixel-ratio CSS media feature. The +value you apply to this feature should be either +"0.75", "1", or "1.5", to indicate that the styles are for devices with low density, medium density, +or high density screens, respectively.

+ +

For example, you can create separate stylesheets for each density:

+ +
+<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.5)" href="hdpi.css" />
+<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.0)" href="mdpi.css" />
+<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 0.75)" href="ldpi.css" />
+
+ + +
+ +

Figure 5. A web page with CSS that's targetted to +specific screen densities using the {@code -webkit-device-pixel-ratio} media feature. Notice +that the hdpi device shows a different image that's applied in CSS.

+
+ +

Or, specify the different styles in one stylesheet:

+ +
+#header {
+    background:url(medium-density-image.png);
+}
+
+@media screen and (-webkit-device-pixel-ratio: 1.5) {
+    // CSS for high-density screens
+    #header {
+        background:url(high-density-image.png);
+    }
+}
+
+@media screen and (-webkit-device-pixel-ratio: 0.75) {
+    // CSS for low-density screens
+    #header {
+        background:url(low-density-image.png);
+    }
+}
+
+ +

Note: The default style for {@code #header} applies the image +designed for medium-density devices in order to support devices running a version of Android less +than 2.0, which do not support the {@code -webkit-device-pixel-ratio} media feature.

+ +

The types of styles you might want to adjust based on the screen density depend on how you've +defined your viewport properties. To provide fully-customized styles that tailor your web page for +each of the supported densities, you should set your viewport properties so the viewport width and +density match the device. That is:

+ +
+<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" />
+
+ +

This way, the Android Browser does not perform scaling on your web page and the viewport width +matches the screen width exactly. On its own, these viewport properties create results shown in +figure 4. However, by adding some custom CSS using the {@code -webkit-device-pixel-ratio} media +feature, you can apply different styles. For example, figure 5 shows a web page with these viewport +properties and also some CSS added that applies a high-resolution image for high-density +screens.

+ + + +

Targetting Device Density with JavaScript

+ +

The Android Browser supports a DOM property that allows you to query the density of the current +device—the window.devicePixelRatio DOM property. The value of this property +specifies the scaling factor used for the current device. For example, if the value +of window.devicePixelRatio is "1.0", then the device is considered a medium density +device and no scaling is applied by default; if the value is "1.5", then the device is +considered a high density device and the page is scaled 1.5x by default; if the value +is "0.75", then the device is considered a low density device and the page is scaled +0.75x by default. Of course, the scaling that the Android Browser applies is based on the web page's +target density—as described in the section about Defining the +viewport target density, the default target is medium-density, but you can change the +target to affect how your web page is scaled for different screen densities.

+ +

For example, here's how you can query the device density with JavaScript:

+ +
+if (window.devicePixelRatio == 1.5) {
+  alert("This is a high-density screen");
+} else if (window.devicePixelRation == 0.75) {
+  alert("This is a low-density screen");
+}
+
+ + + + + + + diff --git a/docs/html/guide/webapps/webview.jd b/docs/html/guide/webapps/webview.jd new file mode 100644 index 0000000..ed28f21 --- /dev/null +++ b/docs/html/guide/webapps/webview.jd @@ -0,0 +1,328 @@ +page.title=Building Web Apps in WebView +@jd:body + +
+
+

Quickview

+
    +
  • Use {@link android.webkit.WebView} to display web pages in your Android application +layout
  • +
  • You can create interfaces from your JavaScript to your client-side Android code
  • +
+ +

In this document

+
    +
  1. Adding a WebView to Your Application
  2. +
  3. Using JavaScript in WebView +
      +
    1. Enabling JavaScript
    2. +
    3. Binding JavaScript code to Android code
    4. +
    +
  4. +
  5. Handling Page Navigation +
      +
    1. Navigating web page history
    2. +
    +
  6. +
+ +

Key classes

+
    +
  1. {@link android.webkit.WebView}
  2. +
  3. {@link android.webkit.WebSettings}
  4. +
  5. {@link android.webkit.WebViewClient}
  6. +
+ +

Related tutorials

+
    +
  1. Web View
  2. +
+ +
+
+ +

If you want to deliver a web application (or just a web page) as a part of a client application, +you can do it using {@link android.webkit.WebView}. The {@link android.webkit.WebView} class is an +extension of Android's {@link android.view.View} class that allows you to display web pages as a +part of your activity layout. It does not include any features of a fully developed web +browser, such as navigation controls or an address bar. All that {@link android.webkit.WebView} +does, by default, is show a web page.

+ +

A common scenario in which using {@link android.webkit.WebView} is helpful is when you want to +provide information in your application that you might need to update, such as an end-user agreement +or a user guide. Within your Android application, you can create an {@link android.app.Activity} +that contains a {@link android.webkit.WebView}, then use that to display your document that's +hosted online.

+ +

Another scenario in which {@link android.webkit.WebView} can help is if your application provides +data to the user that +always requires an Internet connection to retrieve data, such as email. In this case, you might +find that it's easier to build a {@link android.webkit.WebView} in your Android application that +shows a web page with all +the user data, rather than performing a network request, then parsing the data and rendering it in +an Android layout. Instead, you can design a web page that's tailored for Android devices +and then implement a {@link android.webkit.WebView} in your Android application that loads the web +page.

+ +

This document shows you how to get started with {@link android.webkit.WebView} and how to do some +additional things, such as handle page navigation and bind JavaScript from your web page to +client-side code in your Android application.

+ + + +

Adding a WebView to Your Application

+ +

To add a {@link android.webkit.WebView} to your Application, simply include the {@code +<WebView>} element in your activity layout. For example, here's a layout file in which the +{@link android.webkit.WebView} fills the screen:

+ +
+<?xml version="1.0" encoding="utf-8"?>
+<WebView  xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/webview"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+/>
+
+ +

To load a web page in the {@link android.webkit.WebView}, use {@link +android.webkit.WebView#loadUrl(String) loadUrl()}. For example:

+ +
+WebView myWebView = (WebView) findViewById(R.id.webview);
+myWebView.loadUrl("http://www.example.com");
+
+ +

Before this will work, however, your application must have access to the Internet. To get +Internet access, request the {@link android.Manifest.permission#INTERNET} permission in your +manifest file. For example:

+ +
+<manifest ... >
+    <uses-permission android:name="android.permission.INTERNET" />
+    ...
+</manifest>
+
+ +

That's all you need for a basic {@link android.webkit.WebView} that displays a web page.

+ + + + +

Using JavaScript in WebView

+ +

If the web page you plan to load in your {@link android.webkit.WebView} use JavaScript, you +must enable JavaScript for your {@link android.webkit.WebView}. Once JavaScript is enabled, you can +also create interfaces between your application code and your JavaScript code.

+ + +

Enabling JavaScript

+ +

JavaScript is disabled in a {@link android.webkit.WebView} by default. You can enable it +through the {@link +android.webkit.WebSettings} attached to your {@link android.webkit.WebView}. You can retrieve {@link +android.webkit.WebSettings} with {@link android.webkit.WebView#getSettings()}, then enable +JavaScript with {@link android.webkit.WebSettings#setJavaScriptEnabled(boolean) +setJavaScriptEnabled()}.

+ +

For example:

+ +
+WebView myWebView = (WebView) findViewById(R.id.webview);
+WebSettings webSettings = myWebView.getSettings();
+webSettings.setJavaScriptEnabled(true);
+
+ +

{@link android.webkit.WebSettings} provides access to a variety of other settings that you might +find useful. For example, if you're developing a web application +that's designed specifically for the {@link android.webkit.WebView} in your Android application, +then you can define a +custom user agent string with {@link android.webkit.WebSettings#setUserAgentString(String) +setUserAgentString()}, then query the custom user agent in your web page to verify that the +client requesting your web page is actually your Android application.

+ +from your Android SDK {@code tools/} directory +

Binding JavaScript code to Android code

+ +

When developing a web application that's designed specifically for the {@link +android.webkit.WebView} in your Android +application, you can create interfaces between your JavaScript code and client-side Android code. +For example, your JavaScript code can call a method in your Android code to display a {@link +android.app.Dialog}, instead of using JavaScript's {@code alert()} function.

+ +

To bind a new interface between your JavaScript and Android code, call {@link +android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()}, passing it +a class instance to bind to your JavaScript and an interface name that your JavaScript can call to +access the class.

+ +

For example, you can include the following class in your Android application:

+ +
+public class JavaScriptInterface {
+    Context mContext;
+
+    /** Instantiate the interface and set the context */
+    JavaScriptInterface(Context c) {
+        mContext = c;
+    }
+
+    /** Show a toast from the web page */
+    public void showToast(String toast) {
+        Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
+    }
+}
+
+ +

In this example, the {@code JavaScriptInterface} class allows the web page to create a {@link +android.widget.Toast} message, using the {@code showToast()} method.

+ +

You can bind this class to the JavaScript that runs in your {@link android.webkit.WebView} with +{@link android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()} and +name the interface {@code Android}. For example:

+ +
+WebView webView = (WebView) findViewById(R.id.webview);
+webView.addJavascriptInterface(new JavaScriptInterface(this), "Android");
+
+ +

This creates an interface called {@code Android} for JavaScript running in the {@link +android.webkit.WebView}. At this point, your web application has access to the {@code +JavaScriptInterface} class. For example, here's some HTML and JavaScript that creates a toast +message using the new interface when the user clicks a button:

+ +
+<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />
+
+<script type="text/javascript">
+    function showAndroidToast(toast) {
+        Android.showToast(toast);
+    }
+</script>
+
+ +

There's no need to initialize the {@code Android} interface from JavaScript. The {@link +android.webkit.WebView} automatically makes it +available to your web page. So, at the click of the button, the {@code showAndroidToast()} +function uses the {@code Android} interface to call the {@code JavaScriptInterface.showToast()} +method.

+ +

Note: The object that is bound to your JavaScript runs in +another thread and not in the thread in which it was constructed.

+ +

Caution: Using {@link +android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()} allows +JavaScript to control your Android application. This can be a very useful feature or a dangerous +security issue. When the HTML in the {@link android.webkit.WebView} is untrustworthy (for example, +part or all of the HTML +is provided by an unknown person or process), then an attacker can include HTML that executes +your client-side code and possibly any code of the attacker's choosing. As such, you should not use +{@link android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()} unless +you wrote all of the HTML and JavaScript that appears in your {@link android.webkit.WebView}. You +should also not allow the user to +navigate to other web pages that are not your own, within your {@link android.webkit.WebView} +(instead, allow the user's +default browser application to open foreign links—by default, the user's web browser +opens all URL links, so be careful only if you handle page navigation as described in the +following section).

+ + + + +

Handling Page Navigation

+ +

When the user clicks a link from a web page in your {@link android.webkit.WebView}, the default +behavior is +for Android to launch an application that handles URLs. Usually, the default web browser opens and +loads the destination URL. However, you can override this behavior for your {@link +android.webkit.WebView}, +so links open within your {@link android.webkit.WebView}. You can then allow the user to navigate +backward and forward through their web page history that's maintained by your {@link +android.webkit.WebView}.

+ +

To open links clicked by the user, simply provide a {@link +android.webkit.WebViewClient} for your {@link android.webkit.WebView}, using {@link +android.webkit.WebView#setWebViewClient(WebViewClient) setWebViewClient()}. For example:

+ +
+WebView myWebView = (WebView) findViewById(R.id.webview);
+myWebView.{@link android.webkit.WebView#setWebViewClient(WebViewClient) setWebViewClient}(new WebViewClient());
+
+ +

That's it. Now all links the user clicks load in your {@link android.webkit.WebView}.

+ +

If you want more control over where a clicked link load, create your own {@link +android.webkit.WebViewClient} that overrides the {@link +android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String) +shouldOverrideUrlLoading()} method. For example:

+ +
+private class MyWebViewClient extends WebViewClient {
+    @Override
+    public boolean {@link android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String) shouldOverrideUrlLoading}(WebView view, String url) {
+        if (Uri.parse(url).getHost().equals("www.example.com")) {
+            // This is my web site, so do not override; let my WebView load the page
+            return false;
+        }
+        // Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs
+        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+        startActivity(intent);
+        return true;
+    }
+}
+
+ +

Then create an instance of this new {@link android.webkit.WebViewClient} for the {@link +android.webkit.WebView}:

+ +
+WebView myWebView = (WebView) findViewById(R.id.webview);
+myWebView.{@link android.webkit.WebView#setWebViewClient(WebViewClient) setWebViewClient}(new MyWebViewClient());
+
+ +

Now when the user clicks a link, the system calls +{@link android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String) +shouldOverrideUrlLoading()}, which checks whether the URL host matches a specific domain (as defined +above). If it does match, then the method returns false in order to not override the URL +loading (it allows the {@link android.webkit.WebView} to load the URL as usual). If the URL host +does not match, then an {@link android.content.Intent} is created to +launch the default Activity for handling URLs (which resolves to the user's default web +browser).

+ + + + + + +

When your {@link android.webkit.WebView} overrides URL loading, it automatically accumulates a +history of visited web +pages. You can navigate backward and forward through the history with {@link +android.webkit.WebView#goBack()} and {@link android.webkit.WebView#goForward()}.

+ +

For example, here's how your {@link android.app.Activity} can use the device BACK key to navigate +backward:

+ +
+@Override
+public boolean {@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown}(int keyCode, KeyEvent event) {
+    // Check if the key event was the BACK key and if there's history
+    if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.{@link android.webkit.WebView#canGoBack() canGoBack}() {
+        myWebView.{@link android.webkit.WebView#goBack() goBack}();
+        return true;
+    }
+    // If it wasn't the BACK key or there's no web page history, bubble up to the default
+    // system behavior (probably exit the activity)
+    return super.onKeyDown(keyCode, event);
+}
+
+ +

The {@link android.webkit.WebView#canGoBack()} method returns +true if there is actually web page history for the user to visit. Likewise, you can use {@link +android.webkit.WebView#canGoForward()} to check whether there is a forward history. If you don't +perform this check, then once the user reaches the end of the history, {@link +android.webkit.WebView#goBack()} or {@link android.webkit.WebView#goForward()} does nothing.

+ + + + + + -- cgit v1.1