Android WebView上实现JavaScript与Java交互

其实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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<RelativeLayout xmlns:android= "http://schemas.android.com/apk/res/android"
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代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<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")来加载);

效果图:



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

以上内容是针对Android WebView上实现JavaScript与Java交互的全部内容,希望对大家有所帮助!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值