| page.title=Building Web Apps in WebView |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>Quickview</h2> |
| <ul> |
| <li>Use {@link android.webkit.WebView} to display web pages in your Android application |
| layout</li> |
| <li>You can create interfaces from your JavaScript to your client-side Android code</li> |
| </ul> |
| |
| <h2>In this document</h2> |
| <ol> |
| <li><a href="#AddingWebView">Adding a WebView to Your Application</a></li> |
| <li><a href="#UsingJavaScript">Using JavaScript in WebView</a> |
| <ol> |
| <li><a href="#EnablingJavaScript">Enabling JavaScript</a></li> |
| <li><a href="#BindingJavaScript">Binding JavaScript code to Android code</a></li> |
| </ol> |
| </li> |
| <li><a href="#HandlingNavigation">Handling Page Navigation</a> |
| <ol> |
| <li><a href="#NavigatingHistory">Navigating web page history</a></li> |
| </ol> |
| </li> |
| </ol> |
| |
| <h2>Key classes</h2> |
| <ol> |
| <li>{@link android.webkit.WebView}</li> |
| <li>{@link android.webkit.WebSettings}</li> |
| <li>{@link android.webkit.WebViewClient}</li> |
| </ol> |
| |
| <h2>Related tutorials</h2> |
| <ol> |
| <li><a href="{@docRoot}resources/tutorials/views/hello-webview.html">Web View</a></li> |
| </ol> |
| |
| </div> |
| </div> |
| |
| <p>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 <em>not</em> 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.</p> |
| |
| <p>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.</p> |
| |
| <p>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.</p> |
| |
| <p>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.</p> |
| |
| |
| |
| <h2 id="AddingWebView">Adding a WebView to Your Application</h2> |
| |
| <p>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:</p> |
| |
| <pre> |
| <?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" |
| /> |
| </pre> |
| |
| <p>To load a web page in the {@link android.webkit.WebView}, use {@link |
| android.webkit.WebView#loadUrl(String) loadUrl()}. For example:</p> |
| |
| <pre> |
| WebView myWebView = (WebView) findViewById(R.id.webview); |
| myWebView.loadUrl("http://www.example.com"); |
| </pre> |
| |
| <p>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:</p> |
| |
| <pre> |
| <manifest ... > |
| <uses-permission android:name="android.permission.INTERNET" /> |
| ... |
| </manifest> |
| </pre> |
| |
| <p>That's all you need for a basic {@link android.webkit.WebView} that displays a web page.</p> |
| |
| |
| |
| |
| <h2 id="UsingJavaScript">Using JavaScript in WebView</h2> |
| |
| <p>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.</p> |
| |
| |
| <h3 id="EnablingJavaScript">Enabling JavaScript</h3> |
| |
| <p>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()}.</p> |
| |
| <p>For example:</p> |
| |
| <pre> |
| WebView myWebView = (WebView) findViewById(R.id.webview); |
| WebSettings webSettings = myWebView.getSettings(); |
| webSettings.setJavaScriptEnabled(true); |
| </pre> |
| |
| <p>{@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.</p> |
| |
| from your Android SDK {@code tools/} directory |
| <h3 id="BindingJavaScript">Binding JavaScript code to Android code</h3> |
| |
| <p>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.</p> |
| |
| <p>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.</p> |
| |
| <p>For example, you can include the following class in your Android application:</p> |
| |
| <pre> |
| public class WebAppInterface { |
| Context mContext; |
| |
| /** Instantiate the interface and set the context */ |
| WebAppInterface(Context c) { |
| mContext = c; |
| } |
| |
| /** Show a toast from the web page */ |
| @JavascriptInterface |
| public void showToast(String toast) { |
| Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show(); |
| } |
| } |
| </pre> |
| |
| <p class="caution"><strong>Caution:</strong> If you've set your <a |
| href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> |
| to 17 or higher, <strong>you |
| must add the {@code @JavascriptInterface} annotation</strong> to any method that you want |
| available to your JavaScript (the method must also be public). If you do not provide the |
| annotation, the method is not accessible by your web page when running on Android 4.2 or |
| higher.</p> |
| |
| <p>In this example, the {@code WebAppInterface} class allows the web page to create a {@link |
| android.widget.Toast} message, using the {@code showToast()} method.</p> |
| |
| <p>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:</p> |
| |
| <pre> |
| WebView webView = (WebView) findViewById(R.id.webview); |
| webView.addJavascriptInterface(new WebAppInterface(this), "Android"); |
| </pre> |
| |
| <p>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 |
| WebAppInterface} class. For example, here's some HTML and JavaScript that creates a toast |
| message using the new interface when the user clicks a button:</p> |
| |
| <pre> |
| <input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /> |
| |
| <script type="text/javascript"> |
| function showAndroidToast(toast) { |
| Android.showToast(toast); |
| } |
| </script> |
| </pre> |
| |
| <p>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 WebAppInterface.showToast()} |
| method.</p> |
| |
| <p class="note"><strong>Note:</strong> The object that is bound to your JavaScript runs in |
| another thread and not in the thread in which it was constructed.</p> |
| |
| <p class="caution"><strong>Caution:</strong> 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).</p> |
| |
| |
| |
| |
| <h2 id="HandlingNavigation">Handling Page Navigation</h2> |
| |
| <p>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}.</p> |
| |
| <p>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:</p> |
| |
| <pre> |
| WebView myWebView = (WebView) findViewById(R.id.webview); |
| myWebView.{@link android.webkit.WebView#setWebViewClient(WebViewClient) setWebViewClient}(new WebViewClient()); |
| </pre> |
| |
| <p>That's it. Now all links the user clicks load in your {@link android.webkit.WebView}.</p> |
| |
| <p>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:</p> |
| |
| <pre> |
| 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; |
| } |
| } |
| </pre> |
| |
| <p>Then create an instance of this new {@link android.webkit.WebViewClient} for the {@link |
| android.webkit.WebView}:</p> |
| |
| <pre> |
| WebView myWebView = (WebView) findViewById(R.id.webview); |
| myWebView.{@link android.webkit.WebView#setWebViewClient(WebViewClient) setWebViewClient}(new MyWebViewClient()); |
| </pre> |
| |
| <p>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 <em>not</em> 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).</p> |
| |
| |
| |
| |
| <h3 id="NavigatingHistory">Navigating web page history</h3> |
| |
| <p>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()}.</p> |
| |
| <p>For example, here's how your {@link android.app.Activity} can use the device <em>Back</em> button |
| to navigate backward:</p> |
| |
| <pre> |
| @Override |
| public boolean {@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown}(int keyCode, KeyEvent event) { |
| // Check if the key event was the Back button 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); |
| } |
| </pre> |
| |
| <p>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.</p> |
| |
| |
| |
| |
| |
| |