使用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 }