[译文]在WebView上开发Web APPs

来源:互联网 发布:2016网络扫黄最新消息 编辑:程序博客网 时间:2024/06/05 08:32

[译文]原文地址:Building Web Apps in WebView
如果你想开发一个web应用(或者仅仅时一个网页)作为客户端应用的一
部分,你可以使用WebView去实现它. 类WebView继承自View,允许你展示网页内容作为activity布局中的一部分. 它并不包含一个已完整开发的网页浏览器的任何特点,比如导航或者地址栏等等.WebView默认所做的功能就是显示一个网页.
有效利用WebView的一个场景是:当你想提供一些可能需要更新的信息时,比如一个终端用户协议或者一个用户指引.在你的android应用程序里,你可以创建一个包含WebView的Activity,然后使用它去显示你的在线文档.
WebView可以提供帮助的另一个场景是:如果你的应用程序提供了一些需要网络连接来获取的数据给用户,比如email. 在这种情况下,你可能会发现在你的android应用程序中添加一个WebView去显示一个包含所有用户数据的网页会更简单一些,而不是通过发起网络请求,然后解析数据并且在android的布局layout中渲染它. 相反的,你可以专门为android设备设计一个网页,然后在你的android应用程序中实现一个WebView去加载网页.
这篇文章向你展示了如何开始使用一个WebView,以及如何去做一些额外的事情,比如处理网页导航、在你的应用程序中绑定网页上的javascript和客户端代码(下面会有具体的解释和操作).
## 为你的应用程序添加一个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文件中添加INTERNET权限,比如:
<manifest ... >    <uses-permission     android:name="android.permission.INTERNET" />    ...</manifest>    
这就是利用WebView去显示一个网页所需要做的所有基本操作步骤.

## 在WebView中使用JavaScript ##
如果在WebView中加载的网页需要使用javascript,你必须使你的WebView允许javascript,一旦允许了javascript,你也可以为你的应用程序代码和javascript代码创建一个接口(译者注:实际就是建立一种映射关系)
### 允许javascript ###
在WebView中javascript功能默认是禁止的. 你可以通过与WebView相关联的WebSettings去允许javascript功能. 你可以通过getSettings()获得WebSettings实例,然后调用setJavaScriptEnabled()允许javascript功能.
比如:

WebView myWebView = (WebView) findViewById(R.id.webview);WebSettings webSettings = myWebView.getSettings();webSettings.setJavaScriptEnabled(true);    
WebSettings提供了其他一些很有用的设置选项.比如你正在开发一个专门为android应用程序中的WebView设计的网页程序,然后你通过setUserAgentString()定义了一个自定义的用户代理字符串(user agent string),然后在你的网页中查询这个自定义的用户代理去证实请求你的网页内容的客户端就是你的android应用程序.

### 绑定javascript代码和android代码 ###

当你正在开发一个专门为你的应用程序中的WebView设计的网页程序时,你可以在javascript代码和android客户端代码之间创建一个接口. 比如,你的javascript代码可以调用android程序的代码去展示一个Dialog,而不是使用javascript内置的alert()函数.
public class WebAppInterface {    Context mContext;    /** 初始化 */    WebAppInterface(Context c) {        mContext = c;    }    /** 从网页中显示一个Toast */    @JavascriptInterface    public void showToast(String toast) {        Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();    }}    
#### 注意: ####如果你设置你的targetSdkVersion为17或者更高的话,你必须在任何你想在javascript中调用的方法上加上@JavascriptInterface注解(方法也必须是public的). 如果你没有添加这个注解,当应用程序运行在android 4.2或者更高版本中时,你的网页是无法调用这个函数的.在这个例子中,类WebAppInterface允许网页通过调用showToast()方法创建一个Toast消息.你可以通过addJavascriptInterface()方法将这个类绑定到运行在WebView上的javascript中,比如:
WebView webView = (WebView) findViewById(R.id.webview);webView.addJavascriptInterface(new WebAppInterface(this), "Android");
上面的代码为javascript创建了一个名为Android的接口,之后你的网页程序就可以访问类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会自动使得它对你的网页有效. 因此,当你点击按钮的时候,使用Android接口的showAndroidToast()函数可以调用WebAppInterface.showToast()方法.#### 注意: ####这个绑定在你的javascript中的对象是运行在其他线程中的,而不是在创建这个对象所在的线程中.#### 警告: ####使用addJavascriptInterface()允许javascript控制你的android程序. 这个功能可以是一个很有用的特征,也可以是一个危险的安全问题. 当在WebView中的HTML是不可信任的时候(比如,一部分或者全部HTML都是由一个不知道的人或进程提供的),攻击者可以在HTML中执行客户端代码,甚至可能是攻击者选择的任何代码. 假如是这样的话,你就不应该使用addJavascriptInterface(),除非在你的WebView中出现的都是你自己写的HTML或者javascript代码.你也不应该允许用户在你的WebView中导航去其他不属于你的网页站点(但是你可以允许用户默认的浏览器去打开这些链接,用户的网页浏览器可以打开所有的URL链接,所以你需要在处理在下面的部分中描述的导航时小心一点).## 处理页面导航 ##当用户从你的WebView中一个网页上点击了一个链接,默认的行为是android系统会启动一个应用程序去处理URL. 通常是默认浏览器打开和加载目的URL.然而,你可以为你的WebView重写这个行为(方法),可以实现在你的WebView中打开链接. 然后你可以允许用户通过WebView中保持的网页历史记录向前或者向后导航.为了打开用户点击的链接,使用setWebViewClient()为你的WebView提供了一个WebViewClient实例,比如:
WebView myWebView = (WebView) findViewById(R.id.webview);myWebView.setWebViewClient(new WebViewClient());
现在用户点击的所有链接都可以在你的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主机是否匹配一个特殊的域名(就像上面定义的一样).如果它匹配的话就返回false,不去重写URL加载的方式(它允许WebView像往常一样去加载URL). 如果URL主机不匹配,一个Intent(意图)就会被创建去打开默认的Activity去处理URL(实际就是用户的默认浏览器).## 导航网页历史 ##当你的WebView重写了URL的加载方式时,它会自动累积你的浏览历史. 你可以通过goBack()和goForward()向前或者向后导航历史记录(译者注:原文是:You can navigate backward and forward through the history with goBack() and goForward().感觉翻译有点别扭...)比如,这里显示了你的Activity如何利用Back按钮去向后导航的实例:
@Overridepublic 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()方法将不会做任何事情.
0 0
原创粉丝点击