如果你要在手机端实现一个web app或在app里加载一个web页面,那么你就要用到WebView控件。这WebView类是View类的扩展子类,它允许web页面作为应用布局的一部分来展示。它是不具备一个完整的浏览器的那些特性,例如WebView没有导航栏,地址栏等。WebView的默认功能就是去找事WebView。
当你在你的app里面加一些以后可能跟新的信息时(例如用户协议或用户指南),你是用WebView那是非常有帮助的。在你的应用里,你可以创建一个带有WebView的activity,然后展示的你的在线文档信息。
使用WebView比较适合的另一种情况是,当你给用户提供数据的时候总是需要连接服务器去检索数据,例如邮件。你会发现使用webView 在应用里去使用网页展示用户数据相对于每次都去请求网络然后在解析数据然后展示在layout里面更容易简单一些。你可以针对Android设备设计web页面然后在你的Android应用里使用WebView加载它们。
这片文章是展示了如何去开始使用WebView和用它做一些额外的事情。例如在你的Android应用里去处理页面导航和把你页面中的js绑定到客户端代码中。
Adding a WebView to Your Application
在你layout布局中添加<WebView>就可以把WebView添加到你的应用里了。例如下面就是一个铺满整个屏幕的WebView.
<?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" />
加载页面使用loadUrl()方法,例如
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.loadUrl("http://www.example.com");
要注意,你必须在manifest file里设置INTERNET权限,它才能使用。
<manifest ... > <uses-permission android:name="android.permission.INTERNET" /> ... </manifest>
这是WebView去展示页面所需要的最基本的几个方面。
Using JavaScript in WebView(在WebView中使用js)
如果你WebView里面加载的页面要使用js,那你需要在你的WebView里面启用js。一旦你启用了js,你还可以在你的应用代码和js代码之间穿件接口。
Enabling JavaScript
在WebView中js默认的是无法使用的,你可应通过WebSettings
去设置你的WebView,使它能够使用js。你可以通过使用WebView的getSettings()方法得到
WebSettings
的返回值,然后调用WebSettings
的setJavaScriptEnabled()方法来设置使用js。
例如
WebView myWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = myWebView.getSettings(); webSettings.setJavaScriptEnabled(true);
WebSettings提供各种各样的你认为有用的设置权限。如果你在你的应用中使用WebView去开发设计一个Web app,你可以通过使用setUserAgentString()去设置一个用户代理字符串,然后在你的web页面查询这个用户代理头验证这个这个页面请求确实是你的app应用。
来自Android SDK工具/目录中
Binding JavaScript code to Android code
当你在你的app应用里使用WebView开发web应用,你能够在js代码和客户端代码之间去创建接口。例如,js代码去调用你的Android里面的一个方法,去弹出弹框来去替代使用js的alter。
通过调用addJavascriptInterface()方法,可以在js代码和Android代码之间绑定一个接口,它可以把一个实例绑定到js,js可以通过这个接口的名字去调用这可实例。
例如下面:
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(); } }
警告:如果你sdk的版本是17或者是更高,你必须在你想在js中调用的任何方法前添加@JavascriptInterface
注释(这方法必须是public的)。如果你没有提供这个注解,那么这方法就会在4.2或是更高版本上无法运行。
这个实例是WebAppInterface类允许WebView页面用showToast方法去穿件一个Toast信息。,你能用WebView的addJavascriptInterface()
把这个类绑定带你的js里,并且这个接口的名字是"Android".例如:
WebView webView = (WebView) findViewById(R.id.webview); webView.addJavascriptInterface(new WebAppInterface(this), "Android");
运行在WebView里的js通过“Android”去调用这个创建的接口,这时,你的web app就可以访问WebAppInterface类。例如,这里是一些html代码,当通过点击按钮,js调用这new interface接口去创建Toast。
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /> <script type="text/javascript"> unction showAndroidToast(toast) { Android.showToast(toast); } </script>
你不需要在js中初始化这“Android”接口。WebView会自动的使它能够在web页面里使用。因此,点击这个按钮,这个showAndroidToast()将会使用Android 这个接口去调用WebAppInterface.showToast()方法。
注意:这个对象是被绑定在js上运行在另一个线程里,不是在他被创建的线程里。
警告:
使用这个addJavascriptInterface()方法之后,js就被允许控制你的Android应用。这即使非常有用的特性,又可能是非常危险的特性。在webview里,html是靠不住的(例如,html的部分或是全部可能是通过一个不认识的人或程序被提供)。攻击这可在你html里执行你客户端的代码和选择任何代码。如果这样的话,你就不能去使用addJavascriptInterface()
,除非你WebView的html和js全是你自己写的。你应该禁止用户在WebView里去跳转到不是自己页面的第三方其他页面。(去代替这些,默认的用户的浏览器可以打开所有的url链接,因此如果你处理页面跳转,如果有下面所描述的情况,你就应该格外去小心注意)。
Handling Page Navigation(处理页面跳转)
当用户从你webview里点击一个链接,默认的是去加载一个去处理url的应用,通常是默认的浏览器去打开并加载这个url。然而,你能在webview里去覆盖这以默认行为,让url在你自己的webview里面打开。然后你可以用户向后或向前跳转,通过webview维护的web页面的访问记录。
用setWebViewClient().方法提供一个WebViewClient,让用户在自己的webView里面打开链接。
例子:
WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.setWebViewClient(new WebViewClient());
这样做之后,所有的url都会在你的WebView里面打开了。
如果点击链接,你想做其他更多色事的话,你就需要去重写WebViewClient
的shouldOverrideUrlLoading();
实例:
private class MyWebViewClient extends WebViewClient { @Override public boolean 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; } }
然后为WebView创建WebViewClient
的一个实例
WebView myWebView = (WebView) findViewById(R.id.webview); myWebView.setWebViewClient(new MyWebViewClient());
现在,当你点击链接,系统就会去调用shouldOverrideUrlLoading(),检查这个url的host是不是匹配特定的域名(如上面)。如果不匹配这个方法就会返回false,为了不覆盖url加载,如果url的不匹配,就会跳转能默认加载这个URL的activity。
Navigating web page history(浏览历史网页)
当你的WebView复写了url加载,他就会自己记录访问的历史页面。你能用goBack() 和goForward()
.方法,通过这个历史记录向前或向后跳转。
例如,这里是一个点击后退按钮回退网页的操作。
@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()
不会做任何操作。