现在的位置: 首页 > IT运维 > 正文

Android WebView与JS交互

2012年05月16日 IT运维 ⁄ 共 9689字 暂无评论 ⁄ 被围观 15+

听说WebView对Javascript的支持也很强,想从网上找些例子,还很难找,最终从google老家找了一个Java和Javascript互调的例子 ,当时看了,下巴“咣当”就掉在地上了,太强了!这样也行?
整个Eclipse ADT工程例子中都有,这里重点分析一下代码:

  1. public class WebViewDemo extends Activity {
  2.     private WebView mWebView;
  3.     private Handler mHandler = new Handler();
  4.     public void onCreate(Bundle icicle) {
  5.         super.onCreate(icicle);
  6.         setContentView(R.layout.webviewdemo);
  7.         mWebView = (WebView) findViewById(R.id.webview);
  8.         WebSettings webSettings = mWebView.getSettings();
  9.         webSettings.setJavaScriptEnabled(true);
  10.         mWebView.addJavascriptInterface(new Object() {
  11.             public void clickOnAndroid() {
  12.                 mHandler.post(new Runnable() {
  13.                     public void run() {
  14.                         mWebView.loadUrl("javascript:wave()");
  15.                     }
  16.                 });
  17.             }
  18.         }, "demo");
  19.         mWebView.loadUrl("file:///android_asset/demo.html");
  20.     }
  21. }

这里的重点是 addJavascriptInterface(Object obj,String interfaceName)方法,该方法将一个java对象绑定到一个javascript对象中,javascript对象名就是 interfaceName,作用域是Global。这样初始化webview后,在webview加载的页面中就可以直接通过 javascript:window.demo访问到绑定的java对象了。来看看在html中是怎样调用的:

  1. <html>
  2.         <script language="javascript">
  3.                 function wave() {
  4.                     document.getElementById("droid").src="android_waving.png";
  5.                 }
  6.         </script>
  7.         <body>
  8.             <a onClick="window.demo.clickOnAndroid()">
  9.                                 <img id="droid" src="android_normal.png"/><br>
  10.                                 Click me!
  11.             </a>
  12.         </body>
  13. </html>

这样在javascript中就可以调用java对象的clickOnAndroid()方法了,wave()方法是java中调用javascript的例子。

这里还有几个知识点:

1)为了让WebView从apk文件中加载 assets,Android SDK提供了一个schema,前缀为"file:///android_asset/"。WebView遇到这样的schema,就去当前包中的 assets目录中找内容。如上面的"file:///android_asset/demo.html"

2)addJavascriptInterface方法中要绑定的Java对象及方法要运行另外的线程中,不能运行在构造他的线程中,这也是使用Handler的目的。

----------------------------------------------------------------------------------------------------------------------------------

 

在看懂这篇文章之前首先要有javascript基础。

(1) js调用android的方法:
WebView wView;
wView. addJavascriptInterface (Object obj, String interfaceName);
是实例化一个对象,在html的js中调用,第二个参数是实例化对象的别名,如果要使用这个obj,则在js中使用的名字就是interfaceName。

public class jsWebDemo extends Activity {
WebView wView;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
wView = (WebView)findViewById(R.id.wv1);

WebSettings wSet = wView.getSettings();
wSet.setJavaScriptEnabled(true);

ProxyBridge pBridge = new ProxyBridge();
wView.addJavascriptInterface(pBridge, “AliansBridge”);

wView.loadUrl(“file:///android_asset/index.html“);

}

private class ProxyBridge {
public int one () {
return 1;
}
}

}

来看一下index.html的内容:
<html>
<script language=”javascript”>
/* This function is invoked by the activity */
function wave() {
alert(“1″);
document.getElementById(“droid”).src=”android_waving.png”;
alert(“2″);
}
</script>
<body>
<div id=”output”>Test page.</div>

<a onClick=”window.demo.clickOnAndroid()”>
<div style=”width:100px;
margin:0px auto;
padding:10px;
text-align:center;
border:2px solid #202020;” >
<img id=”droid” src=”android_normal.png”/><br>
Click me!
</div>
</a>
<input type=”submit” value=”change to 1″ onclick=”document.getElementById(‘output’).innerHTML =AliansBridge.one()” />
</body>
</html>
这里的AliansBridge即是调用的JAVA对象。

要注意的是,如果你只有一个方法需要被js调用只new一个对象就行:

ProxyBridge pBridge = new ProxyBridge();
wView.addJavascriptInterface(pBridge, “AliansBridge”);

如果你需要调用好多个方法,就要把整个android程序所在的类本身实例化传递进去:

wView.addJavascriptInterface(this, “AliansBridge”);

(2) android调用js的方法:wView.setWebChromeClient (WebChromeClient client)
要用到Handler更新UI,Handler mHandler = new Handler();

mWebView.setWebChromeClient(new MyWebChromeClient());
mWebView.addJavascriptInterface(new Object(){
/**
* This is not called on the UI thread. Post a runnable to invoke
* loadUrl on the UI thread.
*/
public void clickOnAndroid() {

mHandler.post(new Runnable() {
public void run() {
mWebView.loadUrl(“javascript:wave()”);
}
});
}
}, “demo”);

同理,在html中必须有一个名为demo的对象调用clickOnAndroid()方法。

/**
* Provides a hook for calling “alert” from javascript. Useful for
* debugging your javascript.
*/
final class MyWebChromeClient extends WebChromeClient {
@Override
public boolean onJsAlert(WebView view, String url, String message,
JsResult result) {
result.confirm();
return super.onJsAlert(view, url, message, result);
}
}

==========

我 们都知道,手机时代的来临的主要标志是啥?能够方便的接入互联网!互联网展现给我们的方式一般都是网页,网页中又必不可少的拥有javascript,所 以说,android提供对javascript的支持那是迫在眉睫了,幸好,android早就给我们提供了无缝连接。让我们可以通过android与 javascript进行交互。

我们的应用很简单,如图:

Android WebView与JS交互1

Android WebView与JS交互1


我 们有一个输入框,旁边有个按钮,点击按钮就会提示我们输入的内容。当然这只是html中最简单的程序了,但是你将这个程序放入android手机中访问下 试试,它是不会进行提示的。要想让其以android的形式提示用户,我们就需要用到android和javascript的交互。对了,这里展示的是一 个网页哦,代码如下:

js.html

  1. <html>
  2. <head>
  3. <title>js交互android</title>
  4. <mce:script type="text/javascript"><!--
  5.     function show(){
  6.     var a = document.getElementById("text").value;
  7.     alert(a);
  8.     }
  9. // --></mce:script>
  10. </head>
  11. <body>
  12. <form action="">
  13.     <input type="text" id="text" value=""/>
  14.     <input type="button" id="button" onclick="window.chenzheng_java.show()" value="clickme"/>
  15. </form>
  16. </body>
  17. </html>

再看看我们的activity代码:

  1. package cn.com.chenzheng_java.js;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.os.Handler;
  5. import android.util.Log;
  6. import android.webkit.JsResult;
  7. import android.webkit.WebChromeClient;
  8. import android.webkit.WebSettings;
  9. import android.webkit.WebView;
  10. import android.widget.Toast;
  11. public class JavaScriptActivity extends Activity {
  12.     WebView webView;
  13.     Handler handler = new Handler();
  14.     @Override
  15.     public void onCreate(Bundle savedInstanceState) {
  16.         super.onCreate(savedInstanceState);
  17.         setContentView(R.layout.main);
  18.         webView = (WebView) findViewById(R.id.webView1);
  19.         /**
  20.          * webSettings 保存着WebView中的状态信息。当WebView第一次被创建时,webSetting中
  21.          * 存储的都为默认值。WebSetting和WebView是一一绑定的。如果webView被销毁了,那么
  22.          * 我们再次调用webSetting中的方法时,会抛出异常。
  23.          */
  24.         WebSettings webSettings = webView.getSettings();
  25.         webSettings.setJavaScriptEnabled(true);
  26.         webView.loadUrl("file:///data/js.html");
  27.         /***
  28.          *webChromeClient是一个比较神奇的东西,其里面提供了一系列的方法,
  29.          *分别作用于我们的javascript代码调用特定方法时执行,我们一般在其内部
  30.          *将javascript形式的展示切换为android的形式。
  31.          * 例如:我们重写了onJsAlert方法,那么当页面中需要弹出alert窗口时,便
  32.          * 会执行我们的代码,按照我们的Toast的形式提示用户。
  33.          */
  34.         class MyWebChromeClient extends WebChromeClient {
  35.             @Override
  36.             public boolean onJsAlert(WebView view, String url, String message,
  37.                     JsResult result) {
  38.                 Toast.makeText(getApplicationContext(), message,
  39.                         Toast.LENGTH_LONG).show();
  40.                 return true;
  41.             }
  42.         }
  43.         webView.setWebChromeClient(new MyWebChromeClient());
  44.         /*
  45.          * 为javascript提供一个回调的接口,这里要注意,一定要在单独的线程中实现,要不会阻塞线程的
  46.          * addJavascriptInterface(Object obj, String interfaceName)
  47.          * obj代表一个java对象,这里我们一般会实现一个自己的类,类里面提供我们要提供给javascript访问的方法
  48.          * interfaceName则是访问我们在obj中声明的方法时候所用到的js对象,调用模式为window.interfaceName.方法名()
  49.          */
  50.         webView.addJavascriptInterface(new Object() {
  51.             public void show() {
  52.                 handler.post(new Runnable() {
  53.                     @Override
  54.                     public void run() {
  55.                         Log.i("通知", "调用了该方法哦");
  56.                         /*
  57.                          * 通过webView.loadUrl("javascript:xxx")方式就可以调用当前网页中的名称
  58.                          * 为xxx的javascript方法
  59.                          */
  60.                         webView.loadUrl("javascript:show()");
  61.                     }
  62.                 });
  63.             }
  64.         }, "chenzheng_java");
  65.     }
  66. }

 

注意:

1) 为了让WebView从apk文件中加载assets,Android SDK提供了一个schema,前缀为"file:///android_asset/"。WebView遇到这样的schema,就去当前包中的 assets目录中找内容。如上面的"file:///android_asset/demo.html"

2)addJavascriptInterface方法中要绑定的Java对象及方法要运行另外的线程中,不能运行在构造他的线程中,这也是使用Handler的目的。

3)如果你要访问网络,请在androidManifest.xml中加上权限<uses-permission android:name="android.permission.INTERNET"></uses-permission>

---------------------------------------------------------------------------------------------------------

我们在程序中可以看到,android访问网页以及与javascript交互主要用到了这么几个类:

WebView :我们可以认为它就是一个浏览器,会对用户访问的网址进行解析,下载,渲染……,然后返回给用户一个网页。  其内部使用的是webkit渲染引擎,它还包含了一些我们经常使用的功能,比如放大、缩小网页(需要在webSetting中先设置WebSettings.setBuiltInZoomControls(boolean));前进、后退……。

默认情况下,webView对javascript和页面的错误都是忽略的。很多时候,如果我们想要加载一个uri,可能我们更多的会使用这种形式:

  1. Uri uri = Uri.parse("http://www.example.com"); Intent intent = new Intent(Intent.ACTION_VIEW, uri); startActivity(intent);

api中为我们提供了一个通过webView加载页面的例子,

Android WebView与JS交互2

Android WebView与JS交互2

我们可以看到,主要有loadUrl()和loadData()方法。这里请注意各个参数的含义哦、

-------------------------------------------------------------

此外,android还为我们提供了一些类来辅助我们的webview的使用。

WebViewClient:

。WebViewClient就是帮助WebView处理各种通知、请求事件的,具体来说包括:

 

 

onLoadResource:通知webView加载url指定的资源时触发

onPageStart:页面开始加载时触发

onPageFinish:页面加载完毕时触发

onReceiveError:出现错误时触发

WebChromeClient:

WebChromeClient是辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等

onCloseWindow(关闭WebView)

onCreateWindow()

onJsAlert (WebView上alert是弹不出来东西的,需要定制你的WebChromeClient处理弹出)

onJsPrompt

onJsConfirm

onProgressChanged

onReceivedIcon

onReceivedTitle

api中提供给我们一个实例:

Android WebView与JS交互3

Android WebView与JS交互3

WebSetting:和WebView是一一绑定的,控制webview的一些基础设置信息,如是否识别javascript,网页是否可放大缩小等。

--------------------------------------------------------------------------

如果我们想通过webview进行历史网页查看时,一定要注意,先通过如下方法判断下是否可执行该操作才好:

Android WebView与JS交互4

Android WebView与JS交互4

然后就可通过

 

void goBack()

Go back in the history of this WebView.
void goBackOrForward(int steps)

Go to the history item that is the number of steps away from the current item.
void goForward()

Go forward in the history of this WebView.

三个方法进行操作了,其中goBackOrForward传递进负数时为back操作,正数为forward操作。

给我留言

您必须 [ 登录 ] 才能发表留言!

×
#