• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.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
9layout</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,
40you can do it using {@link android.webkit.WebView}. The {@link android.webkit.WebView} class is an
41extension of Android's {@link android.view.View} class that allows you to display web pages as a
42part of your activity layout. It does <em>not</em> include any features of a fully developed web
43browser, such as navigation controls or an address bar. All that {@link android.webkit.WebView}
44does, 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
47provide information in your application that you might need to update, such as an end-user agreement
48or a user guide. Within your Android application, you can create an {@link android.app.Activity}
49that contains a {@link android.webkit.WebView}, then use that to display your document that's
50hosted online.</p>
51
52<p>Another scenario in which {@link android.webkit.WebView} can help is if your application provides
53data to the user that
54always requires an Internet connection to retrieve data, such as email. In this case, you might
55find that it's easier to build a {@link android.webkit.WebView} in your Android application that
56shows a web page with all
57the user data, rather than performing a network request, then parsing the data and rendering it in
58an Android layout. Instead, you can design a web page that's tailored for Android devices
59and then implement a {@link android.webkit.WebView} in your Android application that loads the web
60page.</p>
61
62<p>This document shows you how to get started with {@link android.webkit.WebView} and how to do some
63additional things, such as handle page navigation and bind JavaScript from your web page to
64client-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&lt;WebView&gt;} 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
84android.webkit.WebView#loadUrl(String) loadUrl()}. For example:</p>
85
86<pre>
87WebView myWebView = (WebView) findViewById(R.id.webview);
88myWebView.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
92Internet access, request the {@link android.Manifest.permission#INTERNET} permission in your
93manifest 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
110must enable JavaScript for your {@link android.webkit.WebView}. Once JavaScript is enabled, you can
111also 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
117through the {@link
118android.webkit.WebSettings} attached to your {@link android.webkit.WebView}. You can retrieve {@link
119android.webkit.WebSettings} with {@link android.webkit.WebView#getSettings()}, then enable
120JavaScript with {@link android.webkit.WebSettings#setJavaScriptEnabled(boolean)
121setJavaScriptEnabled()}.</p>
122
123<p>For example:</p>
124
125<pre>
126WebView myWebView = (WebView) findViewById(R.id.webview);
127WebSettings webSettings = myWebView.getSettings();
128webSettings.setJavaScriptEnabled(true);
129</pre>
130
131<p>{@link android.webkit.WebSettings} provides access to a variety of other settings that you might
132find useful. For example, if you're developing a web application
133that's designed specifically for the {@link android.webkit.WebView} in your Android application,
134then you can define a
135custom user agent string with {@link android.webkit.WebSettings#setUserAgentString(String)
136setUserAgentString()}, then query the custom user agent in your web page to verify that the
137client requesting your web page is actually your Android application.</p>
138
139from 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
143android.webkit.WebView} in your Android
144application, you can create interfaces between your JavaScript code and client-side Android code.
145For example, your JavaScript code can call a method in your Android code to display a {@link
146android.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
149android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()}, passing it
150a class instance to bind to your JavaScript and an interface name that your JavaScript can call to
151access the class.</p>
152
153<p>For example, you can include the following class in your Android application:</p>
154
155<pre>
156public 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    &#64;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
173href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a>
174to 17 or higher, <strong>you
175must add the {@code &#64;JavascriptInterface} annotation</strong> to any method that you want
176available to your JavaScript (the method must also be public). If you do not provide the
177annotation, the method is not accessible by your web page when running on Android 4.2 or
178higher.</p>
179
180<p>In this example, the {@code WebAppInterface} class allows the web page to create a {@link
181android.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
185name the interface {@code Android}. For example:</p>
186
187<pre>
188WebView webView = (WebView) findViewById(R.id.webview);
189webView.addJavascriptInterface(new WebAppInterface(this), "Android");
190</pre>
191
192<p>This creates an interface called {@code Android} for JavaScript running in the {@link
193android.webkit.WebView}. At this point, your web application has access to the {@code
194WebAppInterface} class. For example, here's some HTML and JavaScript that creates a toast
195message using the new interface when the user clicks a button:</p>
196
197<pre>
198&lt;input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /&gt;
199
200&lt;script type="text/javascript"&gt;
201    function showAndroidToast(toast) {
202        Android.showToast(toast);
203    }
204&lt;/script&gt;
205</pre>
206
207<p>There's no need to initialize the {@code Android} interface from JavaScript. The {@link
208android.webkit.WebView} automatically makes it
209available to your web page. So, at the click of the button, the {@code showAndroidToast()}
210function uses the {@code Android} interface to call the {@code WebAppInterface.showToast()}
211method.</p>
212
213<p class="note"><strong>Note:</strong> The object that is bound to your JavaScript runs in
214another thread and not in the thread in which it was constructed.</p>
215
216<p class="caution"><strong>Caution:</strong> Using {@link
217android.webkit.WebView#addJavascriptInterface(Object,String) addJavascriptInterface()} allows
218JavaScript to control your Android application. This can be a very useful feature or a dangerous
219security issue. When the HTML in the {@link android.webkit.WebView} is untrustworthy (for example,
220part or all of the HTML
221is provided by an unknown person or process), then an attacker can include HTML that executes
222your 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
224you wrote all of the HTML and JavaScript that appears in your {@link android.webkit.WebView}. You
225should also not allow the user to
226navigate to other web pages that are not your own, within your {@link android.webkit.WebView}
227(instead, allow the user's
228default browser application to open foreign links&mdash;by default, the user's web browser
229opens all URL links, so be careful only if you handle page navigation as described in the
230following 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
238behavior is
239for Android to launch an application that handles URLs. Usually, the default web browser opens and
240loads the destination URL. However, you can override this behavior for your {@link
241android.webkit.WebView},
242so links open within your {@link android.webkit.WebView}. You can then allow the user to navigate
243backward and forward through their web page history that's maintained by your {@link
244android.webkit.WebView}.</p>
245
246<p>To open links clicked by the user, simply provide a {@link
247android.webkit.WebViewClient} for your {@link android.webkit.WebView}, using {@link
248android.webkit.WebView#setWebViewClient(WebViewClient) setWebViewClient()}. For example:</p>
249
250<pre>
251WebView myWebView = (WebView) findViewById(R.id.webview);
252myWebView.{@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
258android.webkit.WebViewClient} that overrides the {@link
259android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String)
260shouldOverrideUrlLoading()} method. For example:</p>
261
262<pre>
263private class MyWebViewClient extends WebViewClient {
264    &#64;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
279android.webkit.WebView}:</p>
280
281<pre>
282WebView myWebView = (WebView) findViewById(R.id.webview);
283myWebView.{@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)
288shouldOverrideUrlLoading()}, which checks whether the URL host matches a specific domain (as defined
289above). If it does match, then the method returns false in order to <em>not</em> override the URL
290loading (it allows the {@link android.webkit.WebView} to load the URL as usual). If the URL host
291does not match, then an {@link android.content.Intent} is created to
292launch the default Activity for handling URLs (which resolves to the user's default web
293browser).</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
301history of visited web
302pages. You can navigate backward and forward through the history with {@link
303android.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
306to navigate backward:</p>
307
308<pre>
309&#64;Override
310public 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) &amp;&amp; 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
323true if there is actually web page history for the user to visit. Likewise, you can use {@link
324android.webkit.WebView#canGoForward()} to check whether there is a forward history. If you don't
325perform this check, then once the user reaches the end of the history, {@link
326android.webkit.WebView#goBack()} or {@link android.webkit.WebView#goForward()} does nothing.</p>
327
328
329
330
331
332
333