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 <?xml version="1.0" encoding="utf-8"?> 76 <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 /> 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 <manifest ... > 97 <uses-permission android:name="android.permission.INTERNET" /> 98 ... 99 </manifest> 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 from your Android SDK {@code tools/} directory 140 <h3 id="BindingJavaScript">Binding JavaScript code to Android code</h3> 141 142 <p>When developing a web application that's designed specifically for the {@link 143 android.webkit.WebView} in your Android 144 application, you can create interfaces between your JavaScript code and client-side Android code. 145 For example, your JavaScript code can call a method in your Android code to display a {@link 146 android.app.Dialog}, instead of using JavaScript's {@code alert()} function.</p> 147 148 <p>To bind a new interface between your JavaScript and Android code, call {@link 149 android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()}, passing it 150 a class instance to bind to your JavaScript and an interface name that your JavaScript can call to 151 access the class.</p> 152 153 <p>For example, you can include the following class in your Android application:</p> 154 155 <pre> 156 public class WebAppInterface { 157 Context mContext; 158 159 /** Instantiate the interface and set the context */ 160 WebAppInterface(Context c) { 161 mContext = c; 162 } 163 164 /** Show a toast from the web page */ 165 @JavascriptInterface 166 public void showToast(String toast) { 167 Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show(); 168 } 169 } 170 </pre> 171 172 <p class="caution"><strong>Caution:</strong> If you've set your <a 173 href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> 174 to 17 or higher, <strong>you 175 must add the {@code @JavascriptInterface} annotation</strong> to any method that you want 176 available to your JavaScript (the method must also be public). If you do not provide the 177 annotation, the method is not accessible by your web page when running on Android 4.2 or 178 higher.</p> 179 180 <p>In this example, the {@code WebAppInterface} class allows the web page to create a {@link 181 android.widget.Toast} message, using the {@code showToast()} method.</p> 182 183 <p>You can bind this class to the JavaScript that runs in your {@link android.webkit.WebView} with 184 {@link android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()} and 185 name the interface {@code Android}. For example:</p> 186 187 <pre> 188 WebView webView = (WebView) findViewById(R.id.webview); 189 webView.addJavascriptInterface(new WebAppInterface(this), "Android"); 190 </pre> 191 192 <p>This creates an interface called {@code Android} for JavaScript running in the {@link 193 android.webkit.WebView}. At this point, your web application has access to the {@code 194 WebAppInterface} class. For example, here's some HTML and JavaScript that creates a toast 195 message using the new interface when the user clicks a button:</p> 196 197 <pre> 198 <input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /> 199 200 <script type="text/javascript"> 201 function showAndroidToast(toast) { 202 Android.showToast(toast); 203 } 204 </script> 205 </pre> 206 207 <p>There's no need to initialize the {@code Android} interface from JavaScript. The {@link 208 android.webkit.WebView} automatically makes it 209 available to your web page. So, at the click of the button, the {@code showAndroidToast()} 210 function uses the {@code Android} interface to call the {@code WebAppInterface.showToast()} 211 method.</p> 212 213 <p class="note"><strong>Note:</strong> The object that is bound to your JavaScript runs in 214 another thread and not in the thread in which it was constructed.</p> 215 216 <p class="caution"><strong>Caution:</strong> Using {@link 217 android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()} allows 218 JavaScript to control your Android application. This can be a very useful feature or a dangerous 219 security issue. When the HTML in the {@link android.webkit.WebView} is untrustworthy (for example, 220 part or all of the HTML 221 is provided by an unknown person or process), then an attacker can include HTML that executes 222 your client-side code and possibly any code of the attacker's choosing. As such, you should not use 223 {@link android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()} unless 224 you wrote all of the HTML and JavaScript that appears in your {@link android.webkit.WebView}. You 225 should also not allow the user to 226 navigate to other web pages that are not your own, within your {@link android.webkit.WebView} 227 (instead, allow the user's 228 default browser application to open foreign links—by default, the user's web browser 229 opens all URL links, so be careful only if you handle page navigation as described in the 230 following section).</p> 231 232 233 234 235 <h2 id="HandlingNavigation">Handling Page Navigation</h2> 236 237 <p>When the user clicks a link from a web page in your {@link android.webkit.WebView}, the default 238 behavior is 239 for Android to launch an application that handles URLs. Usually, the default web browser opens and 240 loads the destination URL. However, you can override this behavior for your {@link 241 android.webkit.WebView}, 242 so links open within your {@link android.webkit.WebView}. You can then allow the user to navigate 243 backward and forward through their web page history that's maintained by your {@link 244 android.webkit.WebView}.</p> 245 246 <p>To open links clicked by the user, simply provide a {@link 247 android.webkit.WebViewClient} for your {@link android.webkit.WebView}, using {@link 248 android.webkit.WebView#setWebViewClient(WebViewClient) setWebViewClient()}. For example:</p> 249 250 <pre> 251 WebView myWebView = (WebView) findViewById(R.id.webview); 252 myWebView.{@link android.webkit.WebView#setWebViewClient(WebViewClient) setWebViewClient}(new WebViewClient()); 253 </pre> 254 255 <p>That's it. Now all links the user clicks load in your {@link android.webkit.WebView}.</p> 256 257 <p>If you want more control over where a clicked link load, create your own {@link 258 android.webkit.WebViewClient} that overrides the {@link 259 android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String) 260 shouldOverrideUrlLoading()} method. For example:</p> 261 262 <pre> 263 private class MyWebViewClient extends WebViewClient { 264 @Override 265 public boolean {@link android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String) shouldOverrideUrlLoading}(WebView view, String url) { 266 if (Uri.parse(url).getHost().equals("www.example.com")) { 267 // This is my web site, so do not override; let my WebView load the page 268 return false; 269 } 270 // Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs 271 Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); 272 startActivity(intent); 273 return true; 274 } 275 } 276 </pre> 277 278 <p>Then create an instance of this new {@link android.webkit.WebViewClient} for the {@link 279 android.webkit.WebView}:</p> 280 281 <pre> 282 WebView myWebView = (WebView) findViewById(R.id.webview); 283 myWebView.{@link android.webkit.WebView#setWebViewClient(WebViewClient) setWebViewClient}(new MyWebViewClient()); 284 </pre> 285 286 <p>Now when the user clicks a link, the system calls 287 {@link android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String) 288 shouldOverrideUrlLoading()}, which checks whether the URL host matches a specific domain (as defined 289 above). If it does match, then the method returns false in order to <em>not</em> override the URL 290 loading (it allows the {@link android.webkit.WebView} to load the URL as usual). If the URL host 291 does not match, then an {@link android.content.Intent} is created to 292 launch the default Activity for handling URLs (which resolves to the user's default web 293 browser).</p> 294 295 296 297 298 <h3 id="NavigatingHistory">Navigating web page history</h3> 299 300 <p>When your {@link android.webkit.WebView} overrides URL loading, it automatically accumulates a 301 history of visited web 302 pages. You can navigate backward and forward through the history with {@link 303 android.webkit.WebView#goBack()} and {@link android.webkit.WebView#goForward()}.</p> 304 305 <p>For example, here's how your {@link android.app.Activity} can use the device <em>Back</em> button 306 to navigate backward:</p> 307 308 <pre> 309 @Override 310 public boolean {@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown}(int keyCode, KeyEvent event) { 311 // Check if the key event was the Back button and if there's history 312 if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.{@link android.webkit.WebView#canGoBack() canGoBack}()) { 313 myWebView.{@link android.webkit.WebView#goBack() goBack}(); 314 return true; 315 } 316 // If it wasn't the Back key or there's no web page history, bubble up to the default 317 // system behavior (probably exit the activity) 318 return super.onKeyDown(keyCode, event); 319 } 320 </pre> 321 322 <p>The {@link android.webkit.WebView#canGoBack()} method returns 323 true if there is actually web page history for the user to visit. Likewise, you can use {@link 324 android.webkit.WebView#canGoForward()} to check whether there is a forward history. If you don't 325 perform this check, then once the user reaches the end of the history, {@link 326 android.webkit.WebView#goBack()} or {@link android.webkit.WebView#goForward()} does nothing.</p> 327 328 329 330 331 332 333