欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android WebView上实现JavaScript与Java交互

程序员文章站 2024-02-25 17:31:27
其实webview加载资源的速度并不慢,但是如果资源多了,当然就很慢。图片、css 、js 、html这些资源每个大概需要10-200ms ,一般都是30ms就ok了。不过...

其实webview加载资源的速度并不慢,但是如果资源多了,当然就很慢。图片、css 、js 、html这些资源每个大概需要10-200ms ,一般都是30ms就ok了。不过webview是必须等到全部资源都完成加载,才会进行渲染的,所以加载的速度很重要!从google上我们了解到,webview加载页面的顺序是:先加载html,然后从里面解析出css、js文件和页面上的图片资源进行加载。如果webkit的缓存里面有,就不加载。加载完这些资源之后,就进行css的渲染和js的执行。css的渲染一般不需要很长时间,几十毫秒就ok。关键是js的执行,如果用了jquery,则执行起来需要5-6秒。而在这段时间,如果不在webview里设置背景,网页部分是白色的,很难看。这是一个很糟糕的用户体验。所以#欧#柏泰#克建议如果用网页布局程序,最好别用那些庞大的js框架。最好使用原生的js写业务脚本,以提升加载速度,改善用户体验。

在混合开发中,有时会用到安卓原生sdk,如调用相机、查看相册、录音等,这就需要web页面中的javascript能调用到安卓sdk接口。由于android的webview是基于webkit内核的,集成了js与java互调的接口函数,可以方便地进行开发使用。

界面布局xml:

<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<webview
android:id="@+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="@+id/linearlayout"
/>
<linearlayout 
android:id="@+id/linearlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignparentbottom="true"
>
<button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="java调用javascript接口"
>
</button>
</linearlayout>
</relativelayout> 

java代码:

private webview webview;
private handler handler = new handler();
private button button;
@suppresslint("setjavascriptenabled")
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
webview = (webview) findviewbyid(r.id.webview);
//自定义webview设置
websettings websettings = webview.getsettings();
websettings.setjavascriptenabled(true);
webview.addjavascriptinterface(new myjavascriptinterface(mainactivity.this), "javainterface");
//如果注释了,javascript中的alert弹窗等就会失效,不显示
webview.setwebchromeclient(new webchromeclient());
//webview.setwebchromeclient(new mywebchromeclient());
//测试webview加载是否正常
//webview.loadurl("http://www.baidu.com/");
webview.setwebviewclient(new hellowebview());
webview.loadurl("file:///android_asset/index.html");
button = (button) findviewbyid(r.id.btn);
button.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view v) {
string param = "bb";
webview.loadurl("javascript:showtitle('"+param+"')");
}
});
}
private class hellowebview extends webviewclient{
@override
public boolean shouldoverrideurlloading(webview view, string url) {
// todo auto-generated method stub
view.loadurl(url);
return true;
} 
}
/**
* 在主线程中定义javascript可以调用的安卓接口
* @author chq
* api 以后,每个被调用java函数都要叫声明 @javascriptinterface
*/
public class myjavascriptinterface{
private context context;
public myjavascriptinterface(context context){
this.context = context;
}
@javascriptinterface
public string tostring() {
return "this is interface";
}
@javascriptinterface
public void clickonandroid() {
toast.maketext(context, "js调用安卓:....", toast.length_short).show();
}
/**
* 安卓调用js接口,要开启子线程调用
*/
@javascriptinterface
public void call() {
toast.maketext(context, "安卓客户端再调用javascript接口", toast.length_short).show();
handler.post(new runnable() { 
@override
public void run() {
string param = "bb";
webview.loadurl("javascript:showtitle('"+param+"')");
}
});
}
}

其中:有几点必须注意的,网上早期关于webview的描述中,有几点变化。1)安卓4.2以上的版本中使用webview实现java与js互调,java接口需要声明@javascriptinterface ; 2)webview要调用setwebchromeclient(),以适应js等弹窗等实现;3)addjavascriptinterface中绑定的接口中调用javascript接口,需要开启子线程来调用(报错:caused by: java.lang.throwable: a webview method was called on thread 'javabridge'. all webview methods must be called on the same thread. );

html代码:

<html>
<script type="text/javascript">
//安卓定义的接口1
function callandroidinterface() {
window.javainterface.clickonandroid();
}
//
function showtitle(param) {
alert("传参:"+param);
var x = document.getelementbyid("title");
alert("标题:"+x.innerhtml);
}
</script>
<body>
<h3 id="title">关于安卓与javascript的交互</h3>
<input type="button" value="调用接口1" onclick="callandroidinterface()"></input> 
<input type="button" value="测试接口可用性" onclick="showtitle('aa')"></input> 
<input type="button" value="调用接口2" onclick="window.javainterface.call()"></input>
</body>
</html> 

以上html文件,其中javainterface就是webview中addjavacriptinterface()方法中注入的接口入口名称,通过该名称就可以直接调用java中的接口。(该html页面需要保持到项目assets目录中,由webview.loadurl("file:///android_asset/index.html")来加载);

效果图:

Android WebView上实现JavaScript与Java交互

其中,对话框弹出:网址为"file://"的网页显示:,如果是服务器上的web页面就会显示源ip地址等等,显然不是我们想要的。下一篇,我们可以重写webchromeclient来修改对话框、确认框等webview的优化。

以上内容是针对android webview上实现javascript与java交互的全部内容,希望对大家有所帮助!