使用js 关闭当前页面 , 一般想到的都是 window.close() , 但是该方法只能关闭通过 window.open() 打开的页面
所以针对这种情况 , 只能分情况去解决 .
在微信 , 支付宝 , app 中打开外部链接 , 都是使用webview打开页面的 , 所以需要app提供映射方法 .
对于微信 , 支付宝 , 我们能通过开放平台找到对应的方法.
微信:
window.WeixinJSBridge.call('closeWindow')
支付宝:
window.AlipayJSBridge.call('closeWebview')
对应一般的app ,需要开发者封装可以让js调用的方法 . (以下就是js 和 app的交互方法)
Javascript调用Java方法
以Android的Toast的为例,下面看下如何从Javascript代码中调用系统的Toast。
先定义一个AndroidToast的Java类,它有一个show的方法用来显示Toast:
public class AndroidToast {
@JavascriptInterface
public void show(String str) {
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
}
}
再对WebView进行设置,开启JavaScipt,注册JavascriptInterface的方法:
private void initView() {
webView = (WebView) findViewById(R.id.webView);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDefaultTextEncodingName("UTF-8");
webView.addJavascriptInterface(new AndroidToast(), "AndroidToast");
webView.loadUrl("file:///android_asset/index.html");
}
addJavascriptInterface的作用是把AndroidToast类映射为Javascript中的AndroidToast。这样就可以在JavaScript中调用Java中的方法了。
在Javascript中调用Java代码:
function toastClick(){
window.AndroidToast.show('from js');
}
通过window属性可以找到映射的对象AndroidToast,直接调用它的show方法即可。
注意这里传输的数据只能是基本数据类型和string,可以传输string就意味着可以使用json传输结构化数据。
这里调用的方法并没有返回值,如果需要在JavaScript中需要得到返回值怎么办呢?JavaScript调用Java有返回值
如果想从Javascript调的方法里面获取到返回值,只需要定义一个带返回值的@JavascriptInterface方法即可:
public class AndroidMessage {
@JavascriptInterface
public String getMsg() {
return "form java";
}
}
添加Javascript的映射:
webView.addJavascriptInterface(new AndroidMessage(), "AndroidMessage");
在JavaScript直接调用:
function showAlert(){
var str=window.AndroidMessage.getMsg();
console.log(str);
}
这样就完成了有返回值的方法调用。还有一种场景是,在Java中主动触发JavaScript方法,就需要在Java中调用JavaScript方法了。Java调用JavaScript方法
Java在调用JavaScript方法的时候,需要使用WebView.loadUrl()方法,它可以直接在页面里执行JavaScript方法。
首先定义一个JavaScript方法给Java调用:
function callFromJava(str){
console.log(str);
}
在Java中直接调用该方法:
public void javaCallJS(){
webView.loadUrl("javascript:callFromJava('call from java')");
}
可以在loadUrl中给Javascript方法直接传参,如果JavaScript方法有返回值,使用WebView.loadUrl()是无法获取到返回值的,需要JavaScript返回值给Java的话,可以定义一个Java方法提供给JavaScript调用,然后Java调用JavaScript之后,JavaScript触发该方法把返回值再传递给Java。
注意WebView.loadUrl()必须在Ui线程中运行,不然会会报错。
以下是项目中用到的具体代码:
var isLppzApp = false
var ua = navigator.userAgent.toLowerCase()
var uaApp = ua ? ua.match(/BeStore/i) : '' // match方法返回的是对象
var uaAndroid = /android/i.test(ua) // test返回的是true/false
var uaIos = /iphone|ipad|ipod/i.test(ua)
if (uaApp.toString() === 'bestore') { // 必须将match返回的对象转成字符串
isLppzApp = true
} else {
isLppzApp = false
}
if (window.WeixinJSBridge) {
window.WeixinJSBridge.call('closeWindow') // 微信
} else if (window.AlipayJSBridge) {
window.AlipayJSBridge.call('closeWebview') // 支付宝
} else if (isLppzApp && uaAndroid) {
window.obj.closePageLppzRequest('') // 安卓app
} else if (isLppzApp && uaIos) {
window.webkit.messageHandlers.closePageLppzRequest.postMessage('') //ios app
}