如果您想了解WKWebView与js交互之完美解决方案的相关知识,那么本文是一篇不可错过的文章,我们将对wkwebview_js与oc交互实例进行全面详尽的解释,并且为您提供关于AndroidWebV
如果您想了解WKWebView与js交互之完美解决方案的相关知识,那么本文是一篇不可错过的文章,我们将对wkwebview_js与oc交互实例进行全面详尽的解释,并且为您提供关于Android WebView与Js交互、Android WebView与JS交互全面详解(小结)、android webview与js交互时遇到的问题解决、Android webview与js交换JSON对象数据示例的有价值的信息。
本文目录一览:- WKWebView与js交互之完美解决方案(wkwebview_js与oc交互实例)
- Android WebView与Js交互
- Android WebView与JS交互全面详解(小结)
- android webview与js交互时遇到的问题解决
- Android webview与js交换JSON对象数据示例
WKWebView与js交互之完美解决方案(wkwebview_js与oc交互实例)
随着H5功能愈发的强大,没进行过混合开发的小伙们都不好意思说自己能够独立进行iOS的app开发,在iOS7操作系统下,常用的native,js交互框架有easy-js,WebViewJavascriptBridge,以及结合javaScriptCore的框架。easy-js 很早的一个框架了,已经好几年没有人维护了,里面有很多隐藏很深的坑,新人如果没有用过的话,建议不要再用了。主要是js新建一个隐藏的iframe,通过拦截url的形式进行交互。WebViewJavascriptBridge是网上很火的一个交互库,使用的人较多,但是对于js基础较弱的小伙伴来说,底层不是太好理解。底层和easy-js一样都是通过创新一个隐藏的iframe通过截取url来进行交互。缺点这里就暂时不说了,用的不多,体会不够深刻。嘿嘿。javaScriptCore中JSExport进行交互,这种方式比较简单易懂,也是我个人比较推崇 的一种方式。如果app最低版本操作系统是iOS7的小伙伴,建议自己搜一下相关知识点哦。但是WKWebView不能够利用javaScriptCore交互,是不是很坑爹哦,呜呜。
由于自己去年的强力推动,今年我们的一系列app最低操作系统都是从iOS8开始,所以今天重点和大家分享一下我是如何实现WKWebView与js交互的。
js发送消息给native的代理方法是:
方法1,
- (void)userContentController:(WKUserContentController *)userContentController
didReceiveScriptMessage:(WKScriptMessage *)message
主要是js方法消息调用native的方法。
native调用js方法传递参数主要通过如下方法:
方法2
[_webView evaluateJavaScript:jsString completionHandler:^(id _Nullable data, NSError * _Nullable error) {
}];
相信这两个方法大家在网上已经看到过很多遍了,貌似可以解决与js交互的问题,实则不然,这两个方法并没有真正的帮我们解决交互的问题。因为在js发送消息给native的时候,有时候需要通过回调来获取相应的信息,仅仅靠上面两个方法是没有办法满足的,也可能会有小伙伴说,先通过上面方法1发送消息个native然后,再使用方法2发送消息给js不就好了么,不行的,这样的话,js调用native方法时,和native发送消息时候并没有时间先后的约定,不能保证,js获取相关返回值的时候,一定能拿到值。
我一直在想如何能有一个与js调用native函数相关连的回调呢。功夫不负有心人,偶然看到H5 ,DOM可以绑定事件,后来想能不能绑定自定义事件呢,一搜果然可以,参考博客如下:
http://www.zhangxinxu.com/wordpress/2012/04/js-dom自定义事件/
顺着这个思路,每一次js方法调用native方法的时候,我都为这个js方法绑定一个对应的callBack方法,这样的话,同时在发送的消息中告诉native需要回调,native方法就可以执行完相关的方法后,直接回调相应的 callBack方法,并携带相关的参数,这样就可以完美的进行交互了。这里我主要写了一个JKEventHandler的js类,脚本内容如下:
var JKEventHandler ={
callNativeFunction:function(functionString,params,callBack){
var methodName = (functionString.replace(/function\s?/mi,"").split("("))[0];
var callBackName =methodName + ''CallBack'';
var message;
if(!callBack){
message = {''methodName'':methodName,''params'':params};
window.webkit.messageHandlers.JKEventHandler.postMessage(message);
}else{
message = {''methodName'':methodName,''params'':params,''callBackName'':callBackName};
if(!Event._listeners[callBackName]){
Event.addEvent(callBackName, function(data){
callBack(data);
});
}
window.webkit.messageHandlers.JKEventHandler.postMessage(message);
}
},
callBack:function(callBackName,data){
Event.fireEvent(callBackName,data);
},
removeAllCallBacks:function(data){
Event._listeners ={};
}
};
var Event = {
_listeners: {},
addEvent: function(type, fn) {
if (typeof this._listeners[type] === "undefined") {
this._listeners[type] = [];
}
if (typeof fn === "function") {
this._listeners[type].push(fn);
}
return this;
},
fireEvent: function(type,param) {
var arrayEvent = this._listeners[type];
if (arrayEvent instanceof Array) {
for (var i=0, length=arrayEvent.length; i<length; i+=1) {
if (typeof arrayEvent[i] === "function") {
arrayEvent[i](param);
}
}
}
return this;
},
removeEvent: function(type, fn) {
var arrayEvent = this._listeners[type];
if (typeof type === "string" && arrayEvent instanceof Array) {
if (typeof fn === "function") {
for (var i=0, length=arrayEvent.length; i<length; i+=1){
if (arrayEvent[i] === fn){
this._listeners[type].splice(i, 1);
break;
}
}
} else {
delete this._listeners[type];
}
}
return this;
}
};
callNativeFunction:
这个函数主要是js调用native方法的时候进行调用的。如果有回调的话,需要在传入的参数中写出来哦。
callBack:
主要是用来触发对应js方法回调函数的。
removeAllCallBacks:
主要是在要销毁所有的callback事件时调用的。
以我的demo为例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>iOS and Js</title>
<style type="text/css">
* {
font-size: 40px;
}
</style>
</head>
<body>
<div>
<h1>教你如何用H5与OC进行交互,并且把H5输入的内容显示到当前的控制器上</h1><br/>
<div><input type="button" value="sendInfoToNative" onclick="sendInfoToNative()"></div>
<br/>
<div><input type="button" value="getInfoFromNative" onclick="getInfoFromNative()"></div>
<br/>
<div><input type="button" value="cleanAllCallBacks" onclick="cleanAllCallBacks()"></div>
<br/>
<div><input type="button" value="点击触发JS方法(callJsConfirm)" onclick="callJsConfirm()"></div><br/>
</div>
<br/>
<div>
<div><input type="button" value="点击触发JS输入方法(callJsInput) " onclick="callJsInput()"></div><br/>
</div>
<br/>
<div id="SwiftDiv">
<span id="jsParamFuncSpan"></span>
</div>
<script type="text/javascript">
function sendInfoToNative() {
var params ={''Phone'':''13566668888''};
JKEventHandler.callNativeFunction(arguments.callee.toString(),params,null);
}
function getInfoFromNative(){
var params = {''Phone'':''13933333333''};
JKEventHandler.callNativeFunction(arguments.callee.toString(),params,function(data){
alert(data);
});
}
function callJsConfirm() {
if (confirm(''confirm'', ''Objective-C call js to show confirm'')) {
document.getElementById(''jsParamFuncSpan'').innerHTML
= ''true'';
} else {
document.getElementById(''jsParamFuncSpan'').innerHTML
= ''false'';
}
}
function callJsInput() {
var response = prompt(''Hello'', ''请输入你的名字:'');
document.getElementById(''jsParamFuncSpan'').innerHTML = response;
alert (response);
}
function cleanAllCallBacks(){
JKEventHandler.removeAllCallBacks();
}
</script>
</body>
</html>
在js中调用getInfoFromNative
这个方法既可以发送参数给native,同时也可以从native获取参数
具体实现:
function getInfoFromNative(){
var params = {''Phone'':''13933333333''};
JKEventHandler.callNativeFunction(arguments.callee.toString(),params,function(data){
alert(data);
});
}
同时呢,通过JKEventHandler的转换,在JKEventHandler+Demo.m文件中有一个同名的函数,只不过是参数不一样:
- (void)getInfoFromNative:(id)params :(void(^)(id response))callBack{
NSLog(@"params %@",params);
NSString *str = @"''Hi Jack!''";
callBack(str);
}
就这样,我在native方法里可以获取到js传递来的参数,同时通过callBack我也可以传递参数给js。
另外呢在JKEventHandler文件里,我写了一个事件分发函数,主要就是为了解决多个js方法交互的问题。感兴趣的小伙伴可以看看我的demo哦。
另外需要大家注意的是,WKWebView所在的ViewController即将被销毁的时候,也就是WKWebView即将被销毁的时候,一定要记得调用如下方法销毁所有的callback事件哦:
[_webView evaluateJavaScript:@"JKEventHandler.removeAllCallBacks();" completionHandler:^(id _Nullable data, NSError * _Nullable error) {
}];//删除所有的回调事件
俗话说的话,代码就是程序员最好的老师,这里我就不多说了,Demo地址
如何使用了cocoapod,可以:
pod "JKWKWebViewHandler"
Android WebView与Js交互
如果是捕获通过http获取的html网页中的连接,可以使用jsoup进行解析获取。示例代码如下:
//通过url字符串,获取html内容,并解析返回一个Document对象
Document doc = Jsoup.parse(url);
//查找所有的a标签
Elements links=content.getElementsByTag("a");
//遍历links元素,获取所有的链接
for(Elementlink:links){
//取得a标签中“href”属性的值,即链接
String linkHref=link.attr("href");
//取得a标签的内容
String linkText=link.text();
//在此对链接地址和内容进行操作和存储
}
这样就可以取得html中所有的链接地址和对应的内容了。
Android WebView与JS交互全面详解(小结)
Android 和 H5 都是移动开发应用的非常广泛。市面上很多App都是使用Android开发的,但使用Android来开发一些比较复杂附属类,提示性的页面是得不偿失的。而H5具有开发速度快,更新不用依赖于App的更新,只需要服务端更新相应的页面即可,所以,App和H5页面相结合就显得尤为重要。而android和H5都不可能每次都是独立存在的,而是相互影响也相互的调用,获取信息等,例如,H5页面要获取App中的用户的基本信息,或者App端要操作H5页面等,下面来看看这两是怎么交互的
目录
1. 交互方式总结
Android与JS通过WebView互相调用方法,实际上是:
- Android去调用JS的代码
- JS去调用Android的代码
二者沟通的桥梁是WebView
对于Android调用JS代码的方法有2种:
- 通过WebView的loadUrl()
- 通过WebView的evaluateJavascript()
对于JS调用Android代码的方法有3种:
- 通过WebView的addJavascriptInterface()进行对象映射
- 通过 WebViewClient 的shouldOverrideUrlLoading ()方法回调拦截 url
- 通过 WebChromeClient的onjsAlert()、onjsConfirm()、onjsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt()消息
2. 具体分析
2.1 Android通过WebView调用 JS 代码
方式1:通过WebView的loadUrl()
实例介绍:点击Android按钮,即调用WebView JS(文本名为javascript)中callJS()
具体使用:
步骤1:将需要调用的JS代码以.html格式放到src/main/assets文件夹里
为了方便展示,本文是采用Andorid调用本地JS代码说明;
实际情况时,Android更多的是调用远程JS代码,即将加载的JS代码路径改成url即可
需要加载JS代码:javascript.html
// 文本名:javascript <!DOCTYPE html> <html> <head> <Meta charset="utf-8"> <title>Carson_Ho</title> // JS代码 <script> // Android需要调用的方法 function callJS(){ alert("Android调用了JS的callJS方法"); } </script> </head> </html>
步骤2:在Android里通过WebView设置调用JS代码
public class MainActivity extends AppCompatActivity { WebView mWebView; Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mWebView =(WebView) findViewById(R.id.webview); WebSettings webSettings = mWebView.getSettings(); // 设置与Js交互的权限 webSettings.setJavaScriptEnabled(true); // 设置允许JS弹窗 webSettings.setJavaScriptCanopenWindowsAutomatically(true); // 先载入JS代码 // 格式规定为:file:///android_asset/文件名.html mWebView.loadUrl("file:///android_asset/javascript.html"); button = (Button) findViewById(R.id.button); button.setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 必须另开线程进行JS方法调用(否则无法调用) mWebView.post(new Runnable() { @Override public void run() { // 注意调用的JS方法名要对应上 // 调用javascript的callJS()方法 mWebView.loadUrl("javascript:callJS()"); } }); } }); // 由于设置了弹窗检验调用结果,所以需要支持js对话框 // webview只是载体,内容的渲染需要使用webviewChromClient类去实现 // 通过设置WebChromeClient对象处理JavaScript的对话框 //设置响应js 的Alert()函数 mWebView.setWebChromeClient(new WebChromeClient() { @Override public boolean onjsAlert(WebView view,String url,String message,final JsResult result) { AlertDialog.Builder b = new AlertDialog.Builder(MainActivity.this); b.setTitle("Alert"); b.setMessage(message); b.setPositiveButton(android.R.string.ok,new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog,int which) { result.confirm(); } }); b.setCancelable(false); b.create().show(); return true; } }); } }
效果图
特别注意:JS代码调用一定要在 onPageFinished() 回调之后才能调用,否则不会调用。
onPageFinished()属于WebViewClient类的方法,主要在页面加载结束时调用
方式2:通过WebView的evaluateJavascript()
优点:
- 该方法比第一种方法效率更高、使用更简洁。
- 因为该方法的执行不会使页面刷新,而第一种方法(loadUrl )的执行则会。
Android 4.4 后才可使用
具体使用
// 只需要将第一种方法的loadUrl()换成下面该方法即可 mWebView.evaluateJavascript("javascript:callJS()",new ValueCallback<String>() { @Override public void onReceiveValue(String value) { //此处为 js 返回的结果 } }); }
2.1.2 方法对比
方式对比图
2.1.3 使用建议
两种方法混合使用,即Android 4.4以下使用方法1,Android 4.4以上方法2
// Android版本变量 final int version = Build.VERSION.SDK_INT; // 因为该方法在 Android 4.4 版本才可使用,所以使用时需进行版本判断 if (version < 18) { mWebView.loadUrl("javascript:callJS()"); } else { mWebView.evaluateJavascript("javascript:callJS()",new ValueCallback<String>() { @Override public void onReceiveValue(String value) { //此处为 js 返回的结果 } }); }
2.2 JS通过WebView调用 Android 代码
2.2.1 方法分析
方式1:通过 WebView的addJavascriptInterface()进行对象映射
步骤1:定义一个与JS对象映射关系的Android类:AndroidtoJs
AndroidtoJs.java(注释已经非常清楚)
// 继承自Object类 public class AndroidtoJs extends Object { // 定义JS需要调用的方法 // 被JS调用的方法必须加入@JavascriptInterface注解 @JavascriptInterface public void hello(String msg) { System.out.println("JS调用了Android的hello方法"); } }
步骤2:将需要调用的JS代码以.html格式放到src/main/assets文件夹里
需要加载JS代码:javascript.html
<!DOCTYPE html> <html> <head> <Meta charset="utf-8"> <title>Carson</title> <script> function callAndroid(){ // 由于对象映射,所以调用test对象等于调用Android映射的对象 test.hello("js调用了android中的hello方法"); } </script> </head> <body> //点击按钮则调用callAndroid函数 <button type="button" id="button1" onclick="callAndroid()"></button> </body> </html>
步骤3:在Android里通过WebView设置Android类与JS代码的映射
public class MainActivity extends AppCompatActivity { WebView mWebView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = mWebView.getSettings(); // 设置与Js交互的权限 webSettings.setJavaScriptEnabled(true); // 通过addJavascriptInterface()将Java对象映射到JS对象 //参数1:Javascript对象名 //参数2:Java对象名 mWebView.addJavascriptInterface(new AndroidtoJs(),"test");//AndroidtoJS类对象映射到js的test对象 // 加载JS代码 // 格式规定为:file:///android_asset/文件名.html mWebView.loadUrl("file:///android_asset/javascript.html");
特点
优点:使用简单,仅将Android对象和JS对象映射即可
缺点:存在严重的漏洞问题
方式2:通过 WebViewClient 的方法shouldOverrideUrlLoading ()回调拦截 url
**具体原理: **
Android通过 WebViewClient 的回调方法shouldOverrideUrlLoading ()拦截 url解析该 url 的协议
如果检测到是预先约定好的协议,就调用相应方法
即JS需要调用Android的方法
具体使用:
步骤1:在JS约定所需要的Url协议
JS代码:javascript.html
以.html格式放到src/main/assets文件夹里
<!DOCTYPE html> <html> <head> <Meta charset="utf-8"> <title>Carson_Ho</title> <script> function callAndroid(){ /*约定的url协议为:js://webview?arg1=111&arg2=222*/ document.location = "js://webview?arg1=111&arg2=222"; } </script> </head> <!-- 点击按钮则调用callAndroid()方法 --> <body> <button type="button" id="button1" onclick="callAndroid()">点击调用Android代码</button> </body> </html>
当该JS通过Android的mWebView.loadUrl("file:///android_asset/javascript.html")加载后,就会回调shouldOverrideUrlLoading (),接下来继续看步骤2:
public class MainActivity extends AppCompatActivity { WebView mWebView; // Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = mWebView.getSettings(); // 设置与Js交互的权限 webSettings.setJavaScriptEnabled(true); // 设置允许JS弹窗 webSettings.setJavaScriptCanopenWindowsAutomatically(true); // 步骤1:加载JS代码 // 格式规定为:file:///android_asset/文件名.html mWebView.loadUrl("file:///android_asset/javascript.html"); // 复写WebViewClient类的shouldOverrideUrlLoading方法 mWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view,String url) { // 步骤2:根据协议的参数,判断是否是所需要的url // 一般根据scheme(协议格式) & authority(协议名)判断(前两个参数) //假定传入进来的 url = "js://webview?arg1=111&arg2=222"(同时也是约定好的需要拦截的) Uri uri = Uri.parse(url); // 如果url的协议 = 预先约定的 js 协议 // 就解析往下解析参数 if ( uri.getScheme().equals("js")) { // 如果 authority = 预先约定协议里的 webview,即代表都符合约定的协议 // 所以拦截url,下面JS开始调用Android需要的方法 if (uri.getAuthority().equals("webview")) { // 步骤3: // 执行JS所需要调用的逻辑 System.out.println("js调用了Android的方法"); // 可以在协议上带有参数并传递到Android上 HashMap<String,String> params = new HashMap<>(); Set<String> collection = uri.getQueryParameterNames(); } return true; } return super.shouldOverrideUrlLoading(view,url); } } ); } }
特点
优点:不存在方式1的漏洞;
缺点:JS获取Android方法的返回值复杂。
如果JS想要得到Android方法的返回值,只能通过 WebView 的 loadUrl ()去执行 JS 方法把返回值传递回去,相关的代码如下:
// Android:MainActivity.java mWebView.loadUrl("javascript:returnResult(" + result + ")"); // JS:javascript.html function returnResult(result){ alert("result is" + result); }
方式3:通过 WebChromeClient的onjsAlert()、onjsConfirm()、onjsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息
在JS中,有三个常用的对话框方法:
常用的对话框方法
方式3的原理:Android通过 WebChromeClient 的onjsAlert()、onjsConfirm()、onjsPrompt()
方法回调分别拦截JS对话框 (即上述三个方法),得到他们的消息内容,然后解析即可。
下面的例子将用拦截 JS的输入框(即prompt()方法)
说明 :
常用的拦截是:拦截 JS的输入框(即prompt()方法)
因为只有prompt()可以返回任意类型的值,操作最全面方便、更加灵活;而alert()对话框没有返回值;confirm()对话框只能返回两种状态(确定 / 取消)两个值
步骤1:加载JS代码,如下: javascript.html
以.html格式放到src/main/assets文件夹里
<!DOCTYPE html> <html> <head> <Meta charset="utf-8"> <title>Carson_Ho</title> <script> function clickprompt(){ // 调用prompt() var result=prompt("js://demo?arg1=111&arg2=222"); alert("demo " + result); } </script> </head> <!-- 点击按钮则调用clickprompt() --> <body> <button type="button" id="button1" onclick="clickprompt()">点击调用Android代码</button> </body> </html>
当使用mWebView.loadUrl("file:///android_asset/javascript.html")加载了上述JS代码后,就会触发回调onjsPrompt(),具体如下:
- 如果是拦截警告框(即alert()),则触发回调onjsAlert();
- 如果是拦截确认框(即confirm()),则触发回调onjsConfirm();
步骤2:在Android通过WebChromeClient复写onjsPrompt()
public class MainActivity extends AppCompatActivity { WebView mWebView; // Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = mWebView.getSettings(); // 设置与Js交互的权限 webSettings.setJavaScriptEnabled(true); // 设置允许JS弹窗 webSettings.setJavaScriptCanopenWindowsAutomatically(true); // 先加载JS代码 // 格式规定为:file:///android_asset/文件名.html mWebView.loadUrl("file:///android_asset/javascript.html"); mWebView.setWebChromeClient(new WebChromeClient() { // 拦截输入框(原理同方式2) // 参数message:代表promt()的内容(不是url) // 参数result:代表输入框的返回值 @Override public boolean onjsPrompt(WebView view,String defaultValue,JsPromptResult result) { // 根据协议的参数,判断是否是所需要的url(原理同方式2) // 一般根据scheme(协议格式) & authority(协议名)判断(前两个参数) //假定传入进来的 url = "js://webview?arg1=111&arg2=222"(同时也是约定好的需要拦截的) Uri uri = Uri.parse(message); // 如果url的协议 = 预先约定的 js 协议 // 就解析往下解析参数 if ( uri.getScheme().equals("js")) { // 如果 authority = 预先约定协议里的 webview,即代表都符合约定的协议 // 所以拦截url,下面JS开始调用Android需要的方法 if (uri.getAuthority().equals("webview")) { // // 执行JS所需要调用的逻辑 System.out.println("js调用了Android的方法"); // 可以在协议上带有参数并传递到Android上 HashMap<String,String> params = new HashMap<>(); Set<String> collection = uri.getQueryParameterNames(); //参数result:代表消息框的返回值(输入值) result.confirm("js调用了Android的方法成功啦"); } return true; } return super.onjsPrompt(view,url,message,defaultValue,result); } // 通过alert()和confirm()拦截的原理相同,此处不作过多讲述 // 拦截JS的警告框 @Override public boolean onjsAlert(WebView view,JsResult result) { return super.onjsAlert(view,result); } // 拦截JS的确认框 @Override public boolean onjsConfirm(WebView view,JsResult result) { return super.onjsConfirm(view,result); } }); } }
2.2.2 三种方式的对比 & 使用场景
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
android webview与js交互时遇到的问题解决
问题如下
1、android调用js方法无效的问题
我的原因是少了
webView.setWebChromeClient(new WebChromeClient());这一句
2、js调用android方法无效的问题
我的原因:在api>17之后为了解决webviewjs调用任意代码的漏洞,要给回调的方法加上
@JavascriptInterface 使用方式可以看下面的源码
解决后的代码:
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; WebView webView; String text; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView= (WebView) findViewById(R.id.main_webview); webView.getSettings().setJavaScriptEnabled(true); webView.setWebChromeClient(new WebChromeClient()); //这一句是为了不让外部链接跳转到其他app去执行,而是在我们自己的webview上显示 // webView.setWebViewClient(new WebViewClient(){ // @Override // public boolean shouldOverrideUrlLoading(WebView view, String url) { // view.loadUrl(url); // return false; // } // }); //我在raw目录下存放了一个test.html文件,代码在后面 InputStream inputStream = getResources().openRawResource(R.raw.test); try { text=readStreamText(inputStream); //加载本地的html文件 webView.loadData(text,"text/html","utf-8"); //设置js回调的方法,回调方法要加上@JavascriptInterface注释,第二个参数对应js中window.demo中的demo webView.addJavascriptInterface(new Object(){ @JavascriptInterface public void clickon(){ Toast.makeText(MainActivity.this, "js call android", Toast.LENGTH_SHORT).show(); } },"demo"); Log.i(TAG,"text="+text); } catch (IOException e) { e.printStackTrace(); } } private String readStreamText(InputStream inputStream) throws IOException { BufferedReader reader=new BufferedReader(new InputStreamReader(inputStream)); StringBuffer b=new StringBuffer(); String temp=null; while ((temp=reader.readLine())!=null) b.append(temp); reader.close(); return b.toString(); } //android调用js的testa函数,加入webView.setWebChromeClient(new WebChromeClient())后成功alert public void c(View v){ new Handler().post(new Runnable() { @Override public void run() { webView.loadUrl("javascript:testa()"); } }); } }
html(raw目录下):
<html> <body> <script language="JavaScript"> function testa() { alert("hello js"); } </script> <font size=31 color=red onclick="window.demo.clickon()">hello js</font> </body> </html>
Android webview与js交换JSON对象数据示例
最近几个项目的测试结果,Android无法主动通过调用webview.loadUrl("javascript:"+callbackFunction+"('"+data+"')"); 这种方式将jsonobject类型的data传给js,因为js那边得到就是一个string的对象。
与此同时,js主动调用android的对象方式,android也无法返回给js一个jsonobject,需要js做一下转换,例如:
Android 代码:
WebView mWebView = (WebView) this.findViewById(R.id.webview);
WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setPluginsEnabled(true);
settings.setAllowFileAccess(true);
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
mWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);//不加上,会显示白边
String url="file:///android_asset/t.html"; //js代码卸载t.html里
NavigationInstance navigation =new NavigationInstance(this);
mWebView.addJavascriptInterface(navigation,"Navigation");
NavigationInstance里的代码:
@Override
public JSONObject GetManeuverInfo() {
try{
JSONObject test=new JSONObject();
test.put("maomao","value");
return test;
//return new JSONObject(bean.ManeuverInfo);
}catch(Exception e){
Log.e(TAG,"",e);
}
return null;
}