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和视觉效果上就会节省很多时间,重复发明轮子没有任何意义。