Android Building web apps in WebView
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
A common scenario in which using
Another scenario in which
This document shows you how to get started with
Then load the page with:
Or load the URL from an HTML string:
For example:
To bind a new interface between your JavaScript and Android code, call
For example, you can include the following class in your Android app:
In this example, the
You can bind this class to the JavaScript that runs in your
This creates an interface called
That's it. Now all links the user clicks load in your
If you want more control over where a clicked link loads, create your own
Then create an instance of this new
Now when the user clicks a link, the system calls
For example, here's how your
The
WebView
. The WebView
class is an
extension of Android's View
class that allows you to display web pages as a
part of your activity layout. It does not include any features of a fully developed web
browser, such as navigation controls or an address bar. All that WebView
does, by default, is show a web page.A common scenario in which using
WebView
is helpful is when you want to
provide information in your app that you might need to update, such as an end-user agreement
or a user guide. Within your Android app, you can create an Activity
that contains a WebView
, then use that to display your document that's
hosted online.Another scenario in which
WebView
can help is if your app 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 WebView
in your Android app 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 WebView
in your Android app that loads the web
page.This document shows you how to get started with
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 app.Adding a WebView to your app
To add aWebView
to your app, you can either include the
<WebView>
element in your activity layout, or set the entire Activity window
as a WebView
in onCreate()
.Adding a WebView in the activity layout
To add aWebView
to your app in the layout, add the following code to your
activity's layout XML file:<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
To load a web page in the WebView
,
use loadUrl()
. For example:
Java
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.loadUrl("http://www.example.com");
Adding a WebView in onCreate()
To add aWebView
to your app in an activity’s onCreate()
method
instead, use logic similar to the following:
Java
WebView myWebView = new WebView(activityContext);
setContentView(myWebView);
Java
myWebView.loadUrl("https://www.example.com");
Java
// Create an unencoded HTML string
// then convert the unencoded HTML string into bytes, encode
// it with Base64, and load the data.
String unencodedHtml =
"<html><body>'%23' is the percent code for ‘#‘ </body></html>";
String encodedHtml = Base64.encodeToString(unencodedHtml.getBytes(),
Base64.NO_PADDING);
myWebView.loadData(encodedHtml, "text/html", "base64");
Note: There are restrictions on what this HTML can do.
See
Before this will work, however, your app must have access to the Internet. To get
Internet access, request the loadData()
and
loadDataWithBaseURL()
for more info about encoding options.
INTERNET
permission in your
manifest file. For example:<manifest ... >
<uses-permission android:name="android.permission.INTERNET" />
...</manifest>
That's all you need for a basic WebView
that displays a web page.
Additionally, you can customize your WebView
by modifying the following:- Enabling fullscreen support with
WebChromeClient
. This class is also called when aWebView
needs permission to alter the host app’s UI, such as creating or closing windows and sending JavaScript dialogs to the user. To learn more about debugging in this context, read Debugging Web Apps. - Handling events that impact content rendering, such as errors on form submissions or
navigation with
WebViewClient
. You can also use this subclass to intercept URL loading. - Enabling JavaScript by modifying
WebSettings
. - Using JavaScript to access Android framework objects that you have injected into a
WebView
.
Using JavaScript in WebView
If the web page you plan to load in yourWebView
uses JavaScript, you
must enable JavaScript for your WebView
. Once JavaScript is enabled, you can
also create interfaces between your app code and your JavaScript code.Enabling JavaScript
JavaScript is disabled in aWebView
by default. You can enable it
through the WebSettings
attached to your WebView
.You can retrieve WebSettings
with getSettings()
, then enable
JavaScript with setJavaScriptEnabled()
.For example:
Java
WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
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 WebView
in your Android app,
then you can define a
custom user agent string with setUserAgentString()
, then query the custom user agent in your web page to verify that the
client requesting your web page is actually your Android app.Binding JavaScript code to Android code
When developing a web application that's designed specifically for theWebView
in your Android
app, 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 Dialog
, instead of using JavaScript's alert()
function.To bind a new interface between your JavaScript and Android code, call
addJavascriptInterface()
, passing it
a class instance to bind to your JavaScript and an interface name that your JavaScript can call to
access the class.For example, you can include the following class in your Android app:
Java
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();
}
}
Caution: If you've set your
targetSdkVersion
to 17 or higher, you
must add the @JavascriptInterface
annotation 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.WebAppInterface
class allows the web page to create a Toast
message, using the showToast()
method.You can bind this class to the JavaScript that runs in your
WebView
with
addJavascriptInterface()
and
name the interface Android
. For example:
Java
WebView webView = (WebView) findViewById(R.id.webview);
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
Android
for JavaScript running in the WebView
. At this point, your web application has access to the 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:<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />
<script type="text/javascript">
function showAndroidToast(toast) {
Android.showToast(toast);
}
</script>
There's no need to initialize the Android
interface from JavaScript. The WebView
automatically makes it
available to your web page. So, at the click of the button, the showAndroidToast()
function uses the Android
interface to call the WebAppInterface.showToast()
method.
Note: The object that is bound to your JavaScript runs in
another thread and not in the thread in which it was constructed.
Caution: Using
addJavascriptInterface()
allows
JavaScript to control your Android app. This can be a very useful feature or a dangerous
security issue. When the HTML in the 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
addJavascriptInterface()
unless
you wrote all of the HTML and JavaScript that appears in your WebView
. You
should also not allow the user to
navigate to other web pages that are not your own, within your 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).Handling page navigation
When the user clicks a link from a web page in yourWebView
, the default
behavior is
for Android to launch an app that handles URLs. Usually, the default web browser opens and
loads the destination URL. However, you can override this behavior for your WebView
,
so links open within your WebView
. You can then allow the user to navigate
backward and forward through their web page history that's maintained by your WebView
.
Note: For security reasons, the system’s browser app doesn’t share
its application data with your app.
To open links clicked by the user, provide a WebViewClient
for your WebView
, using setWebViewClient()
. For example:
Java
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient
(MyWebViewClient);
WebView
.If you want more control over where a clicked link loads, create your own
WebViewClient
that overrides the
shouldOverrideUrlLoading()
method. For example:
Java
private class MyWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading
(WebView view, String url) {
if (Uri.parse(url).getHost().equals("https://www.example.com")) {
// This is my website, 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;
}
}
WebViewClient
for the WebView
:
Java
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient
(new MyWebViewClient());
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 not override the URL
loading (it allows the WebView
to load the URL as usual). If the URL host
does not match, then an Intent
is created to
launch the default Activity for handling URLs (which resolves to the user's default web
browser).Navigating web page history
When yourWebView
overrides URL loading, it automatically accumulates a
history of visited web
pages. You can navigate backward and forward through the history with goBack()
and goForward()
.For example, here's how your
Activity
can use the device Back button
to navigate backward:
Java
@Override
public boolean 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.canGoBack
()) {
myWebView.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);
}
}
canGoBack()
method returns
true if there is actually web page history for the user to visit. Likewise, you can use 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, goBack()
or goForward()
does nothing.Handling device configuration changes
During runtime, activity state changes occur when a device’s configuration changes, such as when users rotate the device or dismiss an input method editor (IME). These changes will cause aWebView
object's activity to be destroyed and
a new activity to be created, which also creates a new WebView
object that will load the destroyed object's URL.
To modify your activity’s default behavior, you can change how it handles orientation
changes in your manifest. To learn more about handling configuration
changes during runtime, read
Handling configuration changes.Managing windows
By default, requests to open new windows are ignored. This is true whether they are opened by JavaScript or by the target attribute in a link. You can customize yourWebChromeClient
to provide your
own behavior for opening multiple windows.
Caution: To keep your app more secure, it's best to prevent
popups and new windows from opening. The safest way to implement this behavior is to pass
"true"
into
setSupportMultipleWindows()
but not override the
onCreateWindow()
method, which setSupportMultipleWindows()
depends on.
Keep in mind, however, that this logic also prevents any page that uses target="_blank"
in its links from loading.
Comments
Post a Comment