上一篇我们学习了( [WebView学习之二]:使用Web Apps 支持不同分辨率屏),今天我们来继续学习。
(博客地址:http://blog.csdn.net/developer_jiangqq),转载请注明。
Author:hmjiangqq
Email:jiangqqlmj@163.com
如果你想要常见一个Web应用程序(或者仅仅是一个网页)来作为客户端应用程序的一部分,你可以使用WebView来实现。WebView是继承与AndroidView类,在上面你可以作为Activity布局的一部分来显示Web页面。这不包括AndroidWeb浏览器的全部功能(例如:没有导航栏以及地址栏),所有的WebView默认情况下只是一个Web页面。
一个通常的应用场景是:你可能需要通过使用ViewView在应用程序(Application)中更新用户终端协议或者用户指南等信息。在你的Android应用程序中你可以创建带有WebView控件的Activity,然后在线显示你的文档。
另外一种应用场景是:如果你的应用程序总需要连接网络来进行获取数据(例如:邮件)。在这个情况下在Android应用程序(Application)中使用WebView来显示所有用户数据而不是执行一个网络请求然后接续数据进行布局显示。相反的你可以在Android应用程序中实现一个WebView来设计加载Web页面。
本文主要讲解一下怎么样开始使用WebView以及一些其他的事情,例如:处理页面导航以及在你的AndroidApplication中从Web页面绑定Javascript到客户端代码中。
(一):在你的AndroidApplication中添加WebView
为了在你的Application中添加一个WebView,只要简单的在你Activity布局中添加<WebView>标签,下面就是一个覆盖全屏幕的WebView的例子布局
<span style="font-size:18px;"><?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"
/>
</span>
然后使用loadUrl()方法来在WebView中加载一个网页
<span style="font-size:18px;">WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.loadUrl("http://www.baidu.com");
</span>
在运行之前,我们的应用需要访问访问,此刻不要忘记在你的配置文件中添加INTERNET访问权限,例如
<span style="font-size:18px;"><manifest ... >
<uses-permission android:name="android.permission.INTERNET" />
...
</manifest>
</span>
以上就是实现了一个基本的WebView。
(二)在WebView中使用Javascript (Using JavascriptInWebView)
如果你在WebView中加载的网页中使用Javascript,你必须为你的WebView开启Javascript支持。一旦Javascript被支持使用,你就可以在你用应用程序代码和Javascript代码之间创建接口。
1.开启Javascript支持(Enabing JavaScript)
Javascript在WebView中默认是关闭的,你可以通过WebSettings调用getSettings()获取WebSettings对象,并且设置setJavaScriptEnab led(true)来开启Javascript支持。例如:
<span style="font-size:18px;">WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
</span>
WebSettings同时提供你可能有用的其他一系列设置方法。例如:你专门为Android应用程序开发基于WebView的WebApp,那么你可以通过调用
setUserAgentString()来自定义设置用户代理,这样就可以验证你的Web页面上面的请求是不是来自Android客户端。
2.绑定Javascript代码到Android中(BindingJavaScriptcode to Androidcode)
当我们在AndroidApplication中设计基于WebView的Web应用程序(Application),这样你可以在Javascript代码和Android客户端代码之间创建接口。例如:Javascript可以调用Andriod代码的方法来显示一个弹框(Dialog),而不是直接使用Javascript的alert()方法。
你可以调用addJavascriptInterface方法,使用一个实例来将你的Javascript和需要Javascript调用的类命名进行绑定,这样你就在javascript代码与Android代码中间就绑定了一个接口。下面来看一个例子:
<span style="font-size:18px;">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();
}
}
</span>
[注]:如果设置targetSdkVersion为17或者更高的时候,你必须在你想访问的Javascript的方法上面添加@JavascriptInterface注解。如果你不添加这个注解,那么你的Web页面程序在Android 4.2或者更高版本中是不会调用该方法。
在上面的例子中 WebAppInterface接口类允许Web页面使用showToast()方法来创建一个toast消息。你可以通过调用addJavaScriptInterface方法来把该类绑定到Javascript中并且命名为"Android",请看下面的例子:
<span style="font-size:18px;">WebView webView = (WebView) findViewById(R.id.webview);
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
</span>
这边为运行在WebView中的JavaScript定义了名字为"Android"的接口.这边你的Web应用可以访问WebAppInterface类。例如:下面的HTML和Javascript脚本可以实现点击按钮的时候显示一个Toast消息。
<inputtype="button" value="Say hello"onClick="showAndroidToast('Hello Android!')" />
<scripttype="text/javascript">
function showAndroidToast(toast) {
Android.showToast(toast);
}
</script>
我们这边不需要进行初始化Android命名的Javascript接口,WebView会自动让你的Web页面可以调用。所以当我们点击button的时候,showAndroidTest()方法会使用Android接口来调用WebAppInterface.showToast()方法
[注]:1.被绑定到Javascript的对象运行在另外一个线程,而不是构造新线程。
2.使用addJavascriptInterface()可以允许JavaScript来控制Android应用程序.这是一个非常有用的特性同时也会出现很严重的安全问题。一旦在WebView中的HTML是不可靠的(例如:部分或者全部HTML代码有一个不知道人或者不知名进程提供),然后攻击者让你的Androi的应用程序执行它提供的HTML代码。除非你写的HTML以及Javascript都会出现WebView中,不然尽量不要使用addJavaScriptInterface()方法。同时你也应该允许用于在WebView中导航到不是你写的其他网页(相反的你可以允许使用默认Web浏览器来打开外部链接,这样你就要进行处理控件页面导航)。
(三)处理页面导航(HandingPage Navigation)
当用户在WebView上点击网页上面的一个链接时,Android会默认启用一个应用程序来处理URL是,通常情况下Web浏览器会默认打开来进行处理加载这些URLs。当然你可以为你的WebView覆盖这个方法,这样可以使用你自己实现的WebView来打开这些链接。你可以允许用户对你的WebView进行向前向后导航页面进行浏览。
你可以使用setWebViewClient()为你自己的WebView提供一个WebViewClient来自己处理打开这些链接地址。例子如下:
<span style="font-size:18px;">WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new WebViewClient());
</span>
现在用户点击的所有链接都会在你自己的WebView中进行加载。
如果你想对于链接的链接更多的控制,你可以创建自己的WebViewClient来进行重写shouldOverrideUrlLoading()方法.例子如下:
<span style="font-size:18px;">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;
}
}
</span>
该为WebView创建一个新WebViewClient实例。
<span style="font-size:18px;">WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new MyWebViewClient());
</span>
那么现在用户进行点击一个链接的时候,系统会自定调用shouldOverrideUrlLoading()方法,该会检查URL是不是匹配特殊对象(例如上面定义的)。
如果不匹配那么这方法会返回一个false表示不重载URL加载(该允许WebView按照默认方法加载URL)。如果该不匹配,那么会创建一个Intent来启动一个新的Activity来处理URLs
(四)导航Web历史页面(Navigating Web page history)
当WebView进行加载URL的时候,该会自动保存历史访问页面。你可以使用goBack()和goForward()方法来进行向前或者向后导航。
下面就是一个例子:你可以使用返回键,来对页面进行回退操作。
<span style="font-size:18px;">@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);
}
</span>
如果该WebView存在用户访问历史记录那么canGoBack()方法会返回true。同样的你可以使用canGoBack()方法来检查是否存在历史记录,如果拟进行这个检查,一旦不存在历史或者最近记录,那么goBack()以及goForward()方法就会抛出异常。
后面的文章会针对该知识点,会专门封装一个WebView组件,这样用起来更加方便点,敬请期待…