329 lines
14 KiB
Plaintext
329 lines
14 KiB
Plaintext
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 JavaScriptInterface {
|
|
Context mContext;
|
|
|
|
/** Instantiate the interface and set the context */
|
|
JavaScriptInterface(Context c) {
|
|
mContext = c;
|
|
}
|
|
|
|
/** Show a toast from the web page */
|
|
public void showToast(String toast) {
|
|
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
|
|
}
|
|
}
|
|
</pre>
|
|
|
|
<p>In this example, the {@code JavaScriptInterface} 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 JavaScriptInterface(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
|
|
JavaScriptInterface} 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 JavaScriptInterface.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 BACK key 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 key 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>
|
|
|
|
|
|
|
|
|
|
|
|
|