如果要将Web
应用程序(或仅仅是网页)作为客户端应用程序的一部分提供,则可以使用WebView
执行此操作。 WebView
类是Android
的View
类的扩展,允许您将Web
页面显示为活动布局的一部分。它不包括完全开发的Web
浏览器的任何功能,例如导航控件或地址栏。默认情况下,WebView
所做的就是显示一个网页。
本文档向您展示了如何开始使用WebView
以及如何执行其他操作,例如处理页面导航以及将网页中的JavaScript
绑定到Android
应用程序中的客户端代码。
一、将WebView添加到您的应用程序
要将WebView
添加到应用程序,可以在活动布局中包含<WebView>
元素,也可以将整个“活动”窗口设置为onCreate()
中的WebView
。
在活动布局中添加WebView
将以下代码添加到活动的布局XML
文件中:
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
要在WebView
中加载网页,请使用loadUrl()
。 例如:
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.loadUrl("http://www.example.com");
在onCreate()中添加WebView
在活动的onCreate()
方法中向您的应用添加WebView
:
WebView myWebView = new WebView(activityContext);
setContentView(myWebView);
然后加载页面:
myWebView.loadUrl("https://www.example.com");
或者从HTML
字符串加载URL
:
// 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");
注意:此
HTML
可以执行的操作有一些限制。 有关编码选项的详细信息,请参阅loadData()
和loadDataWithBaseURL()
。
权限
在此之前,您的应用必须能够访问Internet
。 请在清单文件中请求INTERNET权限:
<manifest ... >
<uses-permission android:name="android.permission.INTERNET" />
...
</manifest>
这就是显示网页的基本WebView
所需的全部内容。 此外,您可以通过修改以下内容来自定义WebView
:
- 使用
WebChromeClient
启用全屏支持。 当WebView
需要更改主机应用程序UI的权限时,也会调用此类,例如创建或关闭窗口以及向用户发送JavaScript
对话框。 - 处理影响内容呈现的事件,例如表单提交上的错误或使用
WebViewClient
导航。 您还可以使用此子类来拦截URL加载。 - 通过修改
WebSettings
启用JavaScript
。 - 使用
JavaScript
访问已注入WebView
的Android
框架对象。
二、在WebView中使用JavaScript
如果您计划在WebView
中加载的网页使用JavaScript
,则必须为WebView
启用JavaScript
。 启用JavaScript
后,您还可以在应用代码和JavaScript
代码之间创建接口。
启用JavaScript
默认情况下,在WebView
中禁用JavaScript
。
WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
WebSettings
提供对您可能会发现有用的各种其他设置的访问。 例如,如果您正在开发专门为Android
应用程序中的WebView
设计的Web
应用程序,则可以使用setUserAgentString()
定义自定义用户代理字符串,然后在网页中查询自定义用户代理以验证,请求您的网页的客户实际上是您的Android
应用。
将JavaScript代码绑定到Android代码
在开发专为Web
应用程序中的WebView
设计的Web
应用程序时,您可以在JavaScript
代码和客户端Android
代码之间创建接口。 例如,您的JavaScript
代码可以调用Android
代码中的方法来显示Dialog
,而不是使用JavaScript
的alert()
函数。
要绑定JavaScript
和Android
代码之间的新接口,请调用addJavascriptInterface()
,向其传递一个类实例以绑定到您的JavaScript
以及您可以调用以访问该类的接口名称。
例如,您可以在Android应用中包含以下类:
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();
}
}
警告:如果已将
targetSdkVersion
设置为17或更高,则必须将@JavascriptInterface
注释添加到您希望JavaScript
可用的任何方法(该方法也必须是公共的)。 如果您未提供注释,则在Android 4.2
或更高版本上运行时,您的网页无法访问该方法。
在此示例中,WebAppInterface
类允许网页使用showToast()
方法创建Toast
消息。
您可以使用addJavascriptInterface()
将此类绑定到在WebView
中运行的JavaScript
,并将接口命名为Android
。 例如:
WebView webView = (WebView) findViewById(R.id.webview);
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
这将在WebView
中创建一个名为Android for JavaScript
的界面。 此时,您的Web
应用程序可以访问WebAppInterface
类。 例如,以下是一些HTML
和JavaScript
,当用户单击按钮时,使用新界面创建Toast
消息:
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />
<script type="text/javascript">
function showAndroidToast(toast) {
Android.showToast(toast);
}
</script>
无需从JavaScript
初始化Android
界面。 WebView
会自动将其提供给您的网页。 因此,只需单击按钮,showAndroidToast()
函数就会使用Android
界面调用WebAppInterface.showToast()
方法。
注意:绑定到
JavaScript
的对象在另一个线程中运行,而不是在构造它的线程中运行。
警告:使用
addJavascriptInterface()
可以让JavaScript
控制您的Android
应用。 这可能是一个非常有用的功能或危险的安全问题。 当WebView
中的HTML
不可信(例如,部分或全部HTML
由未知的人或进程提供)时,攻击者可以包含执行客户端代码的HTML
,也可能包括攻击者选择的任何代码。 因此,除非您编写了WebView中显示的所有HTML
和JavaScript
,否则不应使用addJavascriptInterface()
。 您也不应允许用户在WebView
中导航到不属于您自己的其他网页(而是允许用户的默认浏览器应用程序打开外部链接 - 默认情况下,用户的Web
浏览器会打开所有URL
链接,因此 只有在按照以下部分所述处理页面导航时才要小心)。
三、处理页面导航
当用户从WebView
中的网页单击链接时,Android
的默认行为是启动处理URL
的应用程序。 通常,默认Web
浏览器会打开并加载目标URL
。 但是,您可以为WebView
覆盖此行为,以便在WebView
中打开链接。 然后,您可以允许用户在WebView
维护的网页历史记录中前后导航。
注意:出于安全考虑,系统的浏览器应用程序不会与您的应用共享其应用程序数据。
要打开用户单击的链接,请使用setWebViewClient()
为WebView
提供WebViewClient
。 例如:
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(MyWebViewClient);
现在,用户在WebView
中单击加载的所有链接。
如果您想要更好地控制单击链接的加载位置,请创建自己的WebViewClient来覆盖shouldOverrideUrlLoading()
方法。 例如:
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;
}
}
然后为WebView创建这个新WebViewClient的实例:
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new MyWebViewClient());
现在,当用户单击链接时,系统调用shouldOverrideUrlLoading()
,它会检查URL
主机是否与特定域匹配(如上所述)。 如果它匹配,则该方法返回false以便不覆盖URL
加载(它允许WebView
像往常一样加载URL
)。 如果URL主机不匹配,则会创建一个Intent
以启动处理UR
L的默认活动(解析为用户的默认Web
浏览器)。
浏览网页历史记录
当WebView
覆盖URL
加载时,它会自动累积访问过的网页的历史记录。 您可以使用goBack()
和goForward()
在历史记录中前后导航。
例如,以下是您的Activity
如何使用设备后退按钮向后导航:
@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()
方法返回true
。 同样,您可以使用canGoForward()
来检查是否存在转发历史记录。 如果您不执行此检查,那么一旦用户到达历史记录的末尾,goBack()
或goForward()
就不会执行任何操作。
处理设备配置更改
在运行时期间,当设备的配置发生更改(例如,用户旋转设备或关闭输入法编辑器(IME)时)会发生活动状态更改。 这些更改将导致销毁WebView
对象的活动并创建新活动,这也会创建一个新的WebView
对象,该对象将加载销毁对象的URL
。 要修改活动的默认行为,您可以更改其在清单中处理方向更改的方式。
四、管理窗口
默认情况下,将忽略打开新窗口的请求。 无论是通过JavaScript
还是通过链接中的target
属性打开它都是如此。 您可以自定义WebChromeClient
以提供打开多个窗口的行为。
警告:为了使您的应用更安全,最好防止弹出窗口和新窗口打开。 实现此行为的最安全方法是将“
true
”传递给setSupportMultipleWindows()
,但不覆盖setSupportMultipleWindows()
依赖的onCreateWindow()
方法。 但请记住,此逻辑还会阻止任何在其链接中使用target =“_ blank”
的页面加载。
网友评论