webview判断 js是否有 交互对象
发布网友
发布时间:2022-04-22 06:31
我来回答
共1个回答
热心网友
时间:2022-04-23 03:00
android与js交互有两种方式,第一种是通过系统提供的@JavascriptInterface注解实现,第二种就是js注入。下面来详细讲解一下二者的使用方式,原理,区别。
一、@JavascriptInterface实现
实现步骤:
a.设置WebView支持js脚本
b.为提供给js调用的方法加上@JavascriptInterface注解c.给WebView添加js接口
[java] view plain copy
webView.getSettings().setJavaScriptEnabled(true);webView.addJavascriptInterface(new JSMethod(mContext), "lh");public class JSMethod {
private Context mContext;
public JSMethod(Context mContext) {
this.mContext = mContext;
}
@JavascriptInterface
public void toast(String msg) {
Toast.makeText(mContext, msg == null ? "" : msg, Toast.LENGTH_SHORT).show();}
}
js端调用android方法:
[javascript] view plain copy
lh.toast("Hello,China!");
android端执行js方法:
[java] view plain copy
webView.loadUrl("javascript:console(" + "'Hello,China!'" + ")"");二、js注入实现
先来说说原理吧,当js调用prompt()方法时,WebChromeClient.onJsPrompt()方法会被触发,当js触发Android提供的接口方法时,将该方法的方法名称、参数类型、参数值转成json,然后通过prompt方法传递给android端,android端解析json并通过反射执行对应的方法,同时也支持执行匿名回调。
整个流程比较复杂,看图:
为WebView绑定WebChormeClient监听,在Html加载进度25%时进行js注入(注入的js是根据android提供给js的对象类名动态生成);动态注入的js代码如下:
[javascript] view plain copy
javascript: (function(b) {
console.log("HostApp initialization begin");var a = {
queue: [],
callback: function() {
var d = Array.prototype.slice.call(arguments, 0);//获取该函数参数并转换为Array数组var c = d.shift();//取得数组第一个元素
var e = d.shift();
this.queue[c].apply(this, d);//新建一个对象 属性名称为取得的c,并将d数组作为他的值。然后将这个对象push到queue数组if(!e) {//e为空的时候,将queue数组属性名称为c的对象删除delete this.queue[c]
}
}
};
//各种赋值,最后都等于同一个函数
a.alert = a.alert = a.alert = a.delayJsCallBack = a.getIMSI = a.getOsSdk = a.goBack = a.overloadMethod = a.overloadMethod = a.passJson2Java = a.passLongType = a.retBackPassJson = a.retJavaObject = a.testLossTime = a.toast = a.toast = function() {var f = Array.prototype.slice.call(arguments, 0);if(f.length < 1) {
throw "HostApp call error, message:miss method name"}
var e = [];
//此段判断,然后赋值
for(var h = 1; h < f.length; h++) {
var c = f[h];
var j = typeof c;
e[e.length] = j;
if(j == "function") {
var d = a.queue.length;
a.queue[d] = c;
f[h] = d
}
}
//将匿名对象{method: f.shift(),types: e,args: f}转换成json字符串并用浏览器弹出确认可输入框,然后取得输入框的值json序列化为js对象var g = JSON.parse(prompt(JSON.stringify({method: f.shift(),
types: e,
args: f
})));
if(g.code != 200) {
throw "HostApp call error, code:" + g.code + ", message:" + g.result}
return g.result
};
//获取a的属性值,然后循环
Object.getOwnPropertyNames(a).forEach(function(d) {var c = a[d];
//判断赋值
if(typeof c === "function" && d !== "callback") {a[d] = function() {
//concat 连接两个数组
return c.apply(a, [d].concat(Array.prototype.slice.call(arguments, 0)))}
}
});
b.HostApp = a;
console.log("HostApp initialization end")})(window);//闭包函数默认执行,然后赋给window。这样window.b就可以执行了 b.HostApp就是执行a的内容,但是a具体处理逻辑不对外开放,避免外部污染a内部逻辑代码不难,可以自行理解,其中回调函数被封装在了a对象里面,确保android端可以通过webview.loadUrl()执行回调。
android端回调js代码如下:
[javascript] view plain copy
javascript:HostApp.callback(0, 0 ,"call back haha");android提供的每一个js方法都对应一个JsCallback对象,android就可以通过JsCallback对象来生成并执行回调js的代码。
三、优缺点
a.第一种方式不安全,不添加addJavascriptInterface,甚至默认false,在低于API17的WebView上默认添加"SearchBoxJavaBridge_"到mJavaScriptObjects中。这样就有可能通过用户信任的客户端获取SD卡的数据;b.第一种方式必须要API大于等于17才能使用
c.第一种方式当有js回调函数需要android端执行时,都需要将匿名回调函数赋值给全局函数才能供android端回调,增加了js和android端通信的封装层的低效代码量;而第二种方式则是通过动态注入js的方式则非常方便。
d.第二种方式也有一定*,比如android提供的方法必须是static修饰的,且方法第一个参数必须为WebView,不过这不影响使用。
如何实现WebView和js页面的交互
通过webView.addJavascriptInterface(Object, "name");方法可以实现,其中参数Object表示的是需要与js交互的Java代码所在的类的类名,而参数name则表示js页面用来调用Java代码时的别名.简单来说就是将Java对象和Js对象进行绑定,通过别名可以找到与之关联的Java对象.例如:
WebView js判断是否联网后页面自动跳转
需求:webview和js的交互,在离线进入app时,打开显示的页面是A页面,如果这时变成在线了,那么应该自动跳转到B页面;如果本来就是在在线时打开的app,那么久会直接进入B页面,就算此时变成离线,也不会变到A页面。(假如:WebView myWebView,A页面url为AURL,B页面url为BURL)问题:js端已写有网络...
webviewjavascriptbridge就是jsbridge吗
是的,WebViewJavaScriptBridge就是JSBridge。WebViewJavaScriptBridge和JSBridge都是用于iOS和Android平台的原生代码与WebView中的JavaScript进行交互的桥梁。具体来说,它们提供了一种机制,使得开发者能够在移动应用中的原生部分和WebView加载的网页之间传递数据、调用函数等。这两个术语在本质上是相同的,只是...
Android-webview和js脚本语言交互的时候怎么获取js方法的返回值_百度...
1、通过webview访问js脚本 2、js脚本再调用webview中的java函数把结果返回 示例代码:通过本地的webview打开脚本页面。调用步骤 1、设置webview支持脚本 webSettings.setJavaScriptEnabled(true);2、打开脚本页面 mWebView.loadUrl("file:///android_asset/demo.html");//这里打开该app的asset目录下的dem...
(IOS)UIWebView和JavaScript之间是怎么交互的?
有固有组件webview,经过设置可以让它支持我们的js的渲染,然后在代码中设置(WebViewClient/WebChromeClient)让应用跳转页面时在本webview中跳 转,通过webview.loadurl (String str)方法可以在需要的地方加载我们前端的页面或者调用 前端所定义的方法(wv.loadUrl(“javascript:sendDataToAndroid(‘我是js,...
本吧须知02-26求助,webview检测js代码语法错误
Android中可以通过webview来实现和js的交互,在程序中调用js代码,只需要将webview控件的支持js的属性设置为true,,然后通过loadUrl就可以直接进行调用,如下所示:mWebView.getSettings().setJavaScriptEnabled(true);mWebView.loadUrl("javascript:test()");2.网页上调用android中java代码的方法在网页中...
WKWebView 怎么拦截URL 与JS的交互
Helvetica, sans-serif;">//自己给String做的一个扩展方法,实现判断是否包含 let tel = url.replace("tel:", to: "") //自己给String做的一个扩展方法,实现替换 let url1 = NSURL(string: "tel://" + tel) //自己封装的一个简易的的对话框弹框 HUDialog.showDiaLoge("是...
wkwebview与js交互异步怎么办?
//用一个对象保存oc返回来的键与值 var info = {}; //调用oc原生方法,(注意这是一个异步调用) window.webkit.messageHandlers.getTicket.postMessage(null); //oc那边收到通知成功后,会去执行js里的一个全局函数,并把前端JS需要的值以键值对的方式带给前端 function getMessage(key, ...
用js赋值webview偶尔不显示
出现问题的原因可能有很多,下面给出几个常见的可能原因及解决方法:1. 网络问题:检查网络连接是否正常,确保网页能够正常加载。2. 代码问题:检查赋值webview的相关代码是否正确,是否正确引用了webview的对象。可以通过调试工具检查控制台是否有错误信息。3. 资源文件问题:检查webview加载的页面是否正确,...
JSBridge原理解析——以WebviewJavascriptBridge实现方式为例
实现JSBridge的关键步骤包括:1. 注册Bridge:在webview侧和native侧分别注册bridge,通过一个对象储存所有函数。2. 初始化代码注入:在webview内部注入初始化代码,此代码执行关键操作。3. 监听URL请求:在iOS中,如WKWebview,监听URL请求进行相关处理。4. webview调用native能力:当webview与native端注册...