android中webview控件和javascript交互实例
当我们要实现丰富的图文混排效果的时候,我们一般会使用webview,这是一个功能十分强大的的控件,来看看官方的解释:
AViewthatdisplayswebpages.ThisclassisthebasisuponwhichyoucanrollyourownwebbrowserorsimplydisplaysomeonlinecontentwithinyourActivity.ItusestheWebKitrenderingenginetodisplaywebpagesandincludesmethodstonavigateforwardandbackwardthroughahistory,zoominandout,performtextsearchesandmore.
一个能显示网页内容的View。该类是你实现一个自己的浏览器,或者只是在activity中显示网页内容的基础;它基于WebKit内核来显示网页,并且包含了实现前后翻页、放大缩小,文字搜索方法。
从上面你应该了解到了基本功能,也就是显示网页。这篇文章中我们主要讨论webview和Javascript的交互。如果你的js基础比java基础好的话那么采用这种方式做一些复杂的处理是个不错的选择。
WebView和js的交互包含两方面,一是在html中通过js调用安卓的java代码;二是在安卓java代码中调用js。
一、html中通过js调用java代码
js中调用java代码其实就记住一点,webview设置一个和js交互的接口(注意这里只是一般的意思,并不是java中接口的含义),这个接口其实是一个一般的类,同时为这个接口取一个别名。这个过程如下:
mWebView.addJavascriptInterface(newDemoJavaScriptInterface(),"demo");
new DemoJavaScriptInterface就是这个接口,demo就是这个接口的别名。
上面的代码执行之后在html的js中就能通过别名(这里是“demo”)来调用newDemoJavaScriptInterface类中的任何方法。
如我们想让html中的一个button点击之后调用java中的函数可以这样:
<inputtype="button" value="clickme" onclick="window.demo.clickOnAndroid()"/>
但是因为安全问题,在Android4.2中(如果应用的android:targetSdkVersion数值为17+)JS只能访问带有@JavascriptInterface注解的Java函数。因此如果你的开发版本比较高,需要在被调用的函数前加上@JavascriptInterface注解。
下面是谷歌给出的代码示例:
WebViewDemo.java
packagecom.google.android.webviewdemo; importandroid.app.Activity; importandroid.os.Bundle; importandroid.os.Handler; importandroid.util.Log; importandroid.webkit.JsResult; importandroid.webkit.WebChromeClient; importandroid.webkit.WebSettings; importandroid.webkit.WebView; /** *DemonstrateshowtoembedaWebViewinyouractivity.Alsodemonstrateshow *tohavejavascriptintheWebViewcallintotheactivity,andhowtheactivity *caninvokejavascript. *<p> *Inthisexample,clickingontheandroidintheWebViewwillresultinacallinto *theactivitiescodein{@linkDemoJavaScriptInterface#clickOnAndroid()}.Thiscode *willturnaroundandinvokejavascriptusingthe{@linkWebView#loadUrl(String)} *method. *<p> *Obviouslyallofthiscouldhavebeenaccomplishedwithoutcallingintotheactivity *andthenbackintojavascript,butthiscodeisintendedtoshowhowtosetupthe *codepathsforthissortofcommunication. * */ publicclassWebViewDemoextendsActivity{ privatestaticfinalStringLOG_TAG="WebViewDemo"; privateWebViewmWebView; privateHandlermHandler=newHandler(); @Override publicvoidonCreate(Bundleicicle){ super.onCreate(icicle); setContentView(R.layout.main); mWebView=(WebView)findViewById(R.id.webview); WebSettingswebSettings=mWebView.getSettings(); webSettings.setSavePassword(false); webSettings.setSaveFormData(false); webSettings.setJavaScriptEnabled(true); webSettings.setSupportZoom(false); mWebView.setWebChromeClient(newMyWebChromeClient()); mWebView.addJavascriptInterface(newDemoJavaScriptInterface(),"demo"); mWebView.loadUrl("file:///android_asset/demo.html"); } finalclassDemoJavaScriptInterface{ DemoJavaScriptInterface(){ } /** *ThisisnotcalledontheUIthread.Postarunnabletoinvoke *loadUrlontheUIthread. */ publicvoidclickOnAndroid(){ mHandler.post(newRunnable(){ publicvoidrun(){ mWebView.loadUrl("javascript:wave()"); } }); } } /** *Providesahookforcalling"alert"fromjavascript.Usefulfor *debuggingyourjavascript. */ finalclassMyWebChromeClientextendsWebChromeClient{ @Override publicbooleanonJsAlert(WebViewview,Stringurl,Stringmessage,JsResultresult){ Log.d(LOG_TAG,message); result.confirm(); returntrue; } } }
demo.html
<html> <scriptlanguage="javascript"> /*Thisfunctionisinvokedbytheactivity*/ functionwave(){ alert("1"); document.getElementById("droid").src="android_waving.png"; alert("2"); } </script> <body> <!--Callsintothejavascriptinterfacefortheactivity--> <aonClick="window.demo.clickOnAndroid()"><divstyle="width:80px; margin:0pxauto; padding:10px; text-align:center; border:2pxsolid#202020;"> <imgid="droid"src="android_normal.png"/><br> Clickme! </div></a> </body> </html>
main.xml
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/intro" android:padding="4dip" android:textSize="16sp" /> <WebView android:id="@+id/webview" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" /> </LinearLayout>
二、android调用js
上面的代码在演示如何在js中调用java代码的同时也演示了如何在java中调用js
调用形式:
mWebView.loadUrl("javascript:wave()");
其中wave()是js中的一个方法,当然你可以把这个方法改成其他的方法,也就是android调用其他的方法。
demo的解释:
现在你一定了解了android和js的交互了。是时候分析一些demo了,根据上面讲的你也应该比较清楚了。具体交互流程如下:
①点击图片,则在js端直接调用android上的方法clickOnAndroid();
②clickOnAndroid()方法(利用线程)调用js的方法。
③被②调用的js直接控制html。
个人总结:利用webView的这种方式在有些时候UI布局就可以转成相应的html代码编写了,而html布局样式之类有DW这样强大的工具,而且网上很多源码,很多代码片。在UI和视觉效果上就会节省很多时间,重复发明轮子没有任何意义。