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