您的位置:首页 > 移动开发 > Android开发

Android上实现Java和Js交互

2016-01-10 20:39 344 查看


在Android上实现Java和Js交互

其实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写业务脚本,以提升加载速度,改善用户体验。
Android的webview是基于webkit内核的,webview中集成了js与java互调的接口函数,通过addJavascriptInterface方法,可以将Java的类注册进webkit,给网页上的js进行调用,而且还可以通过loadUrl方法是给webkit传递一个uri,供浏览器来进行解析,实现Java和js交互。
要想运行网页上的js脚本,webview必须设置支持Javascript

Java代码

mWebview.getSettings().setJavaScriptEnabled(true);


然后是设置webview要加载的网页:
web的网页:webView.loadUrl("http://www.google.com");
本地的网页:webView.loadUrl("file:///android_asset/XX.html");//本地的存放在:assets文件夹中

webview做完基本的初始化后我们还要要给它,加进一个回调的代理类JavaScriptInterface,并给它一个调用的名称:ncp

Java代码

//1
Java对象注入到这个WebViewJavaScript上下文,Null值将被忽略2Javascript中暴露的对象
mWebView.addJavascriptInterface(newJavaScriptInterface(),"ncp");


JavaScriptInterface可以是一个普通的Java类,类实现的方法,均可被js回调:

Java代码

finalclassJavaScriptInterface{
publicintcallOnJs(){
return1000;
}
publicvoidcallOnJs2(Stringmode){
//TODO
}
}


Java要调用js的方法,只需知道js的方法名称即可:

Java代码

mWebView.loadUrl("javascript:onSaveCallback()");


js这边就更简单:

Js代码

<scripttype="text/javascript">
window.onload=function(){
document.getElementById('btn_1').addEventListener('click',onBtnClick,false);
var_int_value=window.ncp.callOnJs();
alert("getintfromjava:"+_int_value);
}
functiononBtnClick(){
window.ncp.callOnJs2("click");
}
</script>


Java和js交互有以下一些特点:
1.Java调用js里面的函数,速度并不令人满意,大概一次一两百毫秒吧,如果要做交互性很强的事情,这种速度会让人疯掉的。而反过来就不一样了,js去调java的方法,速度很快,基本上40-50毫秒一次。所以尽量用js调用java方法,而不是java去调用js函数。
2.Java调用js的函数,没有返回值,而Js调用java方法,可以有返回值。返回值可以是基本类型、字符串,也可以是对象。如果是字符串,有个很讨厌的问题,第3点我会讲的。如果是对象,这个对象会被转换为js的对象,直接可以访问里面的方法。但是我不推荐java返回给js的是对象,除非是必须。因为js收到java返回的对象,会产生一些交换对象,而如果这些对象的数量增加到了500或600以上,程序就会出问题。所以尽量返回基本数据类型或者字符串。
3.Js调用Java的方法,返回值如果是字符串,你会发现这个字符串是native的,不能对它进行一些修改操作,比如想对它substr,取不到。怎么解决呢?转成locale的。使用toLocaleString()函数就可以了。不过这个函数的速度并不快,转化的字符串如果很多,将会很耗费时间。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
初始化WebView

publicvoidinitView(Viewv){
WebViewwebview=(WebView)v.findViewById(R.id.web);
webview.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
webview.addJavascriptInterface(newMyWebInterface(mContext),"APP");
initData();
}


初始化WebView数据

privatevoidinitData(){
WebSettingswebSettings=webview.getSettings();
//多窗口
webSettings.supportMultipleWindows();
//启用javascript
webSettings.setJavaScriptEnabled(true);
//javascript可以自动打开窗口
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
//设置是否允许文件访问
webSettings.setAllowFileAccess(true);
webview.setWebChromeClient(newWebChromeClient());
webview.setWebViewClient(newPhoneCardWebViewClient());
webview.loadUrl(thisURL);
//请求获取焦点
webview.requestFocus();
}


classPhoneCardWebViewClientextendsWebViewClient{
@Override
publicvoidonPageStarted(WebViewview,Stringurl,Bitmapfavicon){
super.onPageStarted(view,url,favicon);
}
@Override
publicvoidonReceivedError(WebViewview,interrorCode,Stringdescription,StringfailingUrl){
super.onReceivedError(view,errorCode,description,failingUrl);
}
@Override//对网页中超链接按钮的响应
publicbooleanshouldOverrideUrlLoading(WebViewview,Stringurl){
view.loadUrl(url);
returnsuper.shouldOverrideUrlLoading(view,url);
}
@Override
publicvoidonPageFinished(WebViewview,Stringurl){
webview.setVisibility(View.VISIBLE);
}
}


publicclassMyWebInterface{
ContextmContext;
//各个方法名为javascript的函数名
/**
*Instantiatetheinterfaceandsetthecontext
*/
publicMyWebInterface(Contextc){
mContext=c;
}
//如果target大于等于API17,则需要加上如下注解
@JavascriptInterface
publicvoidDownApp(Stringurl,intuid,Stringnikename){
if(MyConst.SimOk)
MyConst.AiAiFragment.showAiAiTips(url);
}
@JavascriptInterface
publicvoidDownChenren(Stringurl){
if(MyConst.SimOk)
MyConst.ChenRenFragment.DownLoadChenRen(url);
}
@JavascriptInterface
publicvoidDownChenren2(Stringurl){
if(MyConst.SimOk)
if(ApkUnit.getAppIsInstall(mContext,"com.wofuns.TripleFight"))
ApkUnit.RunApp(mContext,"com.wofuns.TripleFight");
else
MyConst.YouXiFragment.DownLoadChenRen(url);
}
@JavascriptInterface
publicvoidDownAiAi(Stringurl){
if(MyConst.SimOk)
MyConst.AiAiFragment.showAiAiTips(url);
}
@JavascriptInterface
publicvoidDownCR(Stringname,Stringurl){
if(MyConst.SimOk)
MyConst.ChenRenFragment.createTipsDialog(name,url);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: