Home | History | Annotate | Download | only in webapps
      1 page.title=Building Web Apps in WebView
      2 @jd:body
      3 
      4 <div id="qv-wrapper">
      5 <div id="qv">
      6 <h2>Quickview</h2>
      7 <ul>
      8   <li>Use {@link android.webkit.WebView} to display web pages in your Android application
      9 layout</li>
     10   <li>You can create interfaces from your JavaScript to your client-side Android code</li>
     11 </ul>
     12 
     13 <h2>In this document</h2>
     14 <ol>
     15   <li><a href="#AddingWebView">Adding a WebView to Your Application</a></li>
     16   <li><a href="#UsingJavaScript">Using JavaScript in WebView</a>
     17     <ol>
     18       <li><a href="#EnablingJavaScript">Enabling JavaScript</a></li>
     19       <li><a href="#BindingJavaScript">Binding JavaScript code to Android code</a></li>
     20     </ol>
     21   </li>
     22   <li><a href="#HandlingNavigation">Handling Page Navigation</a>
     23     <ol>
     24       <li><a href="#NavigatingHistory">Navigating web page history</a></li>
     25     </ol>
     26   </li>
     27 </ol>
     28 
     29 <h2>Key classes</h2>
     30 <ol>
     31   <li>{@link android.webkit.WebView}</li>
     32   <li>{@link android.webkit.WebSettings}</li>
     33   <li>{@link android.webkit.WebViewClient}</li>
     34 </ol>
     35 
     36 <h2>Related tutorials</h2>
     37 <ol>
     38   <li><a href="{@docRoot}resources/tutorials/views/hello-webview.html">Web View</a></li>
     39 </ol>
     40 
     41 </div>
     42 </div>
     43 
     44 <p>If you want to deliver a web application (or just a web page) as a part of a client application,
     45 you can do it using {@link android.webkit.WebView}. The {@link android.webkit.WebView} class is an
     46 extension of Android's {@link android.view.View} class that allows you to display web pages as a
     47 part of your activity layout. It does <em>not</em> include any features of a fully developed web
     48 browser, such as navigation controls or an address bar. All that {@link android.webkit.WebView}
     49 does, by default, is show a web page.</p>
     50 
     51 <p>A common scenario in which using {@link android.webkit.WebView} is helpful is when you want to
     52 provide information in your application that you might need to update, such as an end-user agreement
     53 or a user guide. Within your Android application, you can create an {@link android.app.Activity}
     54 that contains a {@link android.webkit.WebView}, then use that to display your document that's
     55 hosted online.</p>
     56 
     57 <p>Another scenario in which {@link android.webkit.WebView} can help is if your application provides
     58 data to the user that
     59 always requires an Internet connection to retrieve data, such as email. In this case, you might
     60 find that it's easier to build a {@link android.webkit.WebView} in your Android application that
     61 shows a web page with all
     62 the user data, rather than performing a network request, then parsing the data and rendering it in
     63 an Android layout. Instead, you can design a web page that's tailored for Android devices
     64 and then implement a {@link android.webkit.WebView} in your Android application that loads the web
     65 page.</p>
     66 
     67 <p>This document shows you how to get started with {@link android.webkit.WebView} and how to do some
     68 additional things, such as handle page navigation and bind JavaScript from your web page to
     69 client-side code in your Android application.</p>
     70 
     71 
     72 
     73 <h2 id="AddingWebView">Adding a WebView to Your Application</h2>
     74 
     75 <p>To add a {@link android.webkit.WebView} to your Application, simply include the {@code
     76 &lt;WebView&gt;} element in your activity layout. For example, here's a layout file in which the
     77 {@link android.webkit.WebView} fills the screen:</p>
     78 
     79 <pre>
     80 &lt;?xml version="1.0" encoding="utf-8"?&gt;
     81 &lt;WebView  xmlns:android="http://schemas.android.com/apk/res/android"
     82     android:id="@+id/webview"
     83     android:layout_width="fill_parent"
     84     android:layout_height="fill_parent"
     85 /&gt;
     86 </pre>
     87 
     88 <p>To load a web page in the {@link android.webkit.WebView}, use {@link
     89 android.webkit.WebView#loadUrl(String) loadUrl()}. For example:</p>
     90 
     91 <pre>
     92 WebView myWebView = (WebView) findViewById(R.id.webview);
     93 myWebView.loadUrl("http://www.example.com");
     94 </pre>
     95 
     96 <p>Before this will work, however, your application must have access to the Internet. To get
     97 Internet access, request the {@link android.Manifest.permission#INTERNET} permission in your
     98 manifest file. For example:</p>
     99 
    100 <pre>
    101 &lt;manifest ... &gt;
    102     &lt;uses-permission android:name="android.permission.INTERNET" /&gt;
    103     ...
    104 &lt;/manifest&gt;
    105 </pre>
    106 
    107 <p>That's all you need for a basic {@link android.webkit.WebView} that displays a web page.</p>
    108 
    109 
    110 
    111 
    112 <h2 id="UsingJavaScript">Using JavaScript in WebView</h2>
    113 
    114 <p>If the web page you plan to load in your {@link android.webkit.WebView} use JavaScript, you
    115 must enable JavaScript for your {@link android.webkit.WebView}. Once JavaScript is enabled, you can
    116 also create interfaces between your application code and your JavaScript code.</p>
    117 
    118 
    119 <h3 id="EnablingJavaScript">Enabling JavaScript</h3>
    120 
    121 <p>JavaScript is disabled in a {@link android.webkit.WebView} by default. You can enable it
    122 through the {@link
    123 android.webkit.WebSettings} attached to your {@link android.webkit.WebView}. You can retrieve {@link
    124 android.webkit.WebSettings} with {@link android.webkit.WebView#getSettings()}, then enable
    125 JavaScript with {@link android.webkit.WebSettings#setJavaScriptEnabled(boolean)
    126 setJavaScriptEnabled()}.</p>
    127 
    128 <p>For example:</p>
    129 
    130 <pre>
    131 WebView myWebView = (WebView) findViewById(R.id.webview);
    132 WebSettings webSettings = myWebView.getSettings();
    133 webSettings.setJavaScriptEnabled(true);
    134 </pre>
    135 
    136 <p>{@link android.webkit.WebSettings} provides access to a variety of other settings that you might
    137 find useful. For example, if you're developing a web application
    138 that's designed specifically for the {@link android.webkit.WebView} in your Android application,
    139 then you can define a
    140 custom user agent string with {@link android.webkit.WebSettings#setUserAgentString(String)
    141 setUserAgentString()}, then query the custom user agent in your web page to verify that the
    142 client requesting your web page is actually your Android application.</p>
    143 
    144 from your Android SDK {@code tools/} directory
    145 <h3 id="BindingJavaScript">Binding JavaScript code to Android code</h3>
    146 
    147 <p>When developing a web application that's designed specifically for the {@link
    148 android.webkit.WebView} in your Android
    149 application, you can create interfaces between your JavaScript code and client-side Android code.
    150 For example, your JavaScript code can call a method in your Android code to display a {@link
    151 android.app.Dialog}, instead of using JavaScript's {@code alert()} function.</p>
    152 
    153 <p>To bind a new interface between your JavaScript and Android code, call {@link
    154 android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()}, passing it
    155 a class instance to bind to your JavaScript and an interface name that your JavaScript can call to
    156 access the class.</p>
    157 
    158 <p>For example, you can include the following class in your Android application:</p>
    159 
    160 <pre>
    161 public class JavaScriptInterface {
    162     Context mContext;
    163 
    164     /** Instantiate the interface and set the context */
    165     JavaScriptInterface(Context c) {
    166         mContext = c;
    167     }
    168 
    169     /** Show a toast from the web page */
    170     public void showToast(String toast) {
    171         Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
    172     }
    173 }
    174 </pre>
    175 
    176 <p>In this example, the {@code JavaScriptInterface} class allows the web page to create a {@link
    177 android.widget.Toast} message, using the {@code showToast()} method.</p>
    178 
    179 <p>You can bind this class to the JavaScript that runs in your {@link android.webkit.WebView} with
    180 {@link android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()} and
    181 name the interface {@code Android}. For example:</p>
    182 
    183 <pre>
    184 WebView webView = (WebView) findViewById(R.id.webview);
    185 webView.addJavascriptInterface(new JavaScriptInterface(this), "Android");
    186 </pre>
    187 
    188 <p>This creates an interface called {@code Android} for JavaScript running in the {@link
    189 android.webkit.WebView}. At this point, your web application has access to the {@code
    190 JavaScriptInterface} class. For example, here's some HTML and JavaScript that creates a toast
    191 message using the new interface when the user clicks a button:</p>
    192 
    193 <pre>
    194 &lt;input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /&gt;
    195 
    196 &lt;script type="text/javascript"&gt;
    197     function showAndroidToast(toast) {
    198         Android.showToast(toast);
    199     }
    200 &lt;/script&gt;
    201 </pre>
    202 
    203 <p>There's no need to initialize the {@code Android} interface from JavaScript. The {@link
    204 android.webkit.WebView} automatically makes it
    205 available to your web page. So, at the click of the button, the {@code showAndroidToast()}
    206 function uses the {@code Android} interface to call the {@code JavaScriptInterface.showToast()}
    207 method.</p>
    208 
    209 <p class="note"><strong>Note:</strong> The object that is bound to your JavaScript runs in
    210 another thread and not in the thread in which it was constructed.</p>
    211 
    212 <p class="caution"><strong>Caution:</strong> Using {@link
    213 android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()} allows
    214 JavaScript to control your Android application. This can be a very useful feature or a dangerous
    215 security issue. When the HTML in the {@link android.webkit.WebView} is untrustworthy (for example,
    216 part or all of the HTML
    217 is provided by an unknown person or process), then an attacker can include HTML that executes
    218 your client-side code and possibly any code of the attacker's choosing. As such, you should not use
    219 {@link android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()} unless
    220 you wrote all of the HTML and JavaScript that appears in your {@link android.webkit.WebView}. You
    221 should also not allow the user to
    222 navigate to other web pages that are not your own, within your {@link android.webkit.WebView}
    223 (instead, allow the user's
    224 default browser application to open foreign links&mdash;by default, the user's web browser
    225 opens all URL links, so be careful only if you handle page navigation as described in the
    226 following section).</p>
    227 
    228 
    229 
    230 
    231 <h2 id="HandlingNavigation">Handling Page Navigation</h2>
    232 
    233 <p>When the user clicks a link from a web page in your {@link android.webkit.WebView}, the default
    234 behavior is
    235 for Android to launch an application that handles URLs. Usually, the default web browser opens and
    236 loads the destination URL. However, you can override this behavior for your {@link
    237 android.webkit.WebView},
    238 so links open within your {@link android.webkit.WebView}. You can then allow the user to navigate
    239 backward and forward through their web page history that's maintained by your {@link
    240 android.webkit.WebView}.</p>
    241 
    242 <p>To open links clicked by the user, simply provide a {@link
    243 android.webkit.WebViewClient} for your {@link android.webkit.WebView}, using {@link
    244 android.webkit.WebView#setWebViewClient(WebViewClient) setWebViewClient()}. For example:</p>
    245 
    246 <pre>
    247 WebView myWebView = (WebView) findViewById(R.id.webview);
    248 myWebView.{@link android.webkit.WebView#setWebViewClient(WebViewClient) setWebViewClient}(new WebViewClient());
    249 </pre>
    250 
    251 <p>That's it. Now all links the user clicks load in your {@link android.webkit.WebView}.</p>
    252 
    253 <p>If you want more control over where a clicked link load, create your own {@link
    254 android.webkit.WebViewClient} that overrides the {@link
    255 android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String)
    256 shouldOverrideUrlLoading()} method. For example:</p>
    257 
    258 <pre>
    259 private class MyWebViewClient extends WebViewClient {
    260     &#64;Override
    261     public boolean {@link android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String) shouldOverrideUrlLoading}(WebView view, String url) {
    262         if (Uri.parse(url).getHost().equals("www.example.com")) {
    263             // This is my web site, so do not override; let my WebView load the page
    264             return false;
    265         }
    266         // Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs
    267         Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
    268         startActivity(intent);
    269         return true;
    270     }
    271 }
    272 </pre>
    273 
    274 <p>Then create an instance of this new {@link android.webkit.WebViewClient} for the {@link
    275 android.webkit.WebView}:</p>
    276 
    277 <pre>
    278 WebView myWebView = (WebView) findViewById(R.id.webview);
    279 myWebView.{@link android.webkit.WebView#setWebViewClient(WebViewClient) setWebViewClient}(new MyWebViewClient());
    280 </pre>
    281 
    282 <p>Now when the user clicks a link, the system calls
    283 {@link android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String)
    284 shouldOverrideUrlLoading()}, which checks whether the URL host matches a specific domain (as defined
    285 above). If it does match, then the method returns false in order to <em>not</em> override the URL
    286 loading (it allows the {@link android.webkit.WebView} to load the URL as usual). If the URL host
    287 does not match, then an {@link android.content.Intent} is created to
    288 launch the default Activity for handling URLs (which resolves to the user's default web
    289 browser).</p>
    290 
    291 
    292 
    293 
    294 <h3 id="NavigatingHistory">Navigating web page history</h3>
    295 
    296 <p>When your {@link android.webkit.WebView} overrides URL loading, it automatically accumulates a
    297 history of visited web
    298 pages. You can navigate backward and forward through the history with {@link
    299 android.webkit.WebView#goBack()} and {@link android.webkit.WebView#goForward()}.</p>
    300 
    301 <p>For example, here's how your {@link android.app.Activity} can use the device BACK key to navigate
    302 backward:</p>
    303 
    304 <pre>
    305 &#64;Override
    306 public boolean {@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown}(int keyCode, KeyEvent event) {
    307     // Check if the key event was the BACK key and if there's history
    308     if ((keyCode == KeyEvent.KEYCODE_BACK) &amp;&amp; myWebView.{@link android.webkit.WebView#canGoBack() canGoBack}() {
    309         myWebView.{@link android.webkit.WebView#goBack() goBack}();
    310         return true;
    311     }
    312     // If it wasn't the BACK key or there's no web page history, bubble up to the default
    313     // system behavior (probably exit the activity)
    314     return super.onKeyDown(keyCode, event);
    315 }
    316 </pre>
    317 
    318 <p>The {@link android.webkit.WebView#canGoBack()} method returns
    319 true if there is actually web page history for the user to visit. Likewise, you can use {@link
    320 android.webkit.WebView#canGoForward()} to check whether there is a forward history. If you don't
    321 perform this check, then once the user reaches the end of the history, {@link
    322 android.webkit.WebView#goBack()} or {@link android.webkit.WebView#goForward()} does nothing.</p>
    323 
    324 
    325 
    326 
    327 
    328 
    329