H5 与Native的交互方案
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了H5 与Native的交互方案相关的知识,希望对你有一定的参考价值。
参考技术A App里基本都少不了H5页面,因此JS与Native之间的通信不可避免,最近留意了一些方案,做下总结。ios有两种webview,ios8以上推出了WKWebView,低于ios8用的是UIWebView,WKWebView性能上优于UIWebView
Native调用javascript语言,是通过UIWebView组件的stringByEvaluatingJavaScriptFromString方法来实现的,该方法返回js脚本的执行结果。
双方只需要约定好JS端函数名称及参数
JS调用Native,并没有现成的API可以使用,需要借助iframe来实现。原理是在UIWebView内发起的所有网络请求,都可以通过delegate函数在Native层得到通知。所以只需要劫持该UIWebView内的所有请求(通常是这样的格式: jsbridge://methodName?param1=value1¶m2=value2 ),然后在UIWebView的delegate函数中,只要发现是jsbridge://开头的地址,就不进行内容的加载,转而执行相应的调用逻辑:
在android里是使用webview的loadUrl进行调用的
有两种比较好的方式:
JS端可以直接调用:alert(AndroidJS.getUserData()) //UserDate
基于 callHandler 和 registerHandler的方式,比较干净
1、 Web 与 App 数据交互原理和实现
2、 WK 与 JS 的那些事
3、 H5 与 Native 交互之 JSBridge 技术
4、 WebView 开车指南之最全实用案例
Android WebView开发:WebView与Native交互
一、Android WebView开发(一):基础应用
二、Android WebView开发(二):WebView与Native交互
三、Android WebView开发(三):WebView性能优化
四、Android WebView开发(四):WebView独立进程解决方案
五、Android WebView开发(五):自定义WebView工具栏
附GitHub源码:WebViewExplore
一、JS调用Native的三种方式:
1、通过WebView的addJavascriptInterface进行对象映射:
需要注意的是这种调用方式,如果你的 minSdkVersion <=16那么需要考虑到4.2之前的漏洞问题。
mWebView.addJavascriptInterface(new JsCallAndroidInterface(), "JSCallBackInterface");
/**
* JS调用android原生方法1:
*
* 通过WebView的addJavascriptInterface()进行对象映射
*/
private class JsCallAndroidInterface
/**
*@JavascriptInterface注解方法.
* js端调用,4.2以后安全;4.2以前,当JS拿到Android这个对象后,
* 就可以调用这个Android对象中所有的方法,包括系统类(java.lang.Runtime 类)
* 从而进行任意代码执行。
* @param msg
*/
@JavascriptInterface
public void callback(String msg)
ToastUtil.showToast(APIWebViewActivity.this, "JS方法回调到web了 :" + msg);
2、通过WebViewClient shouldOverrideUrlLoading方法回调拦截url:
与上一篇讲到的url重定向类似,可在此做url的拦截,已达到针对性的调用native方法的目的。
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
if (resolveShouldLoadLogic(url))
return true;
return super.shouldOverrideUrlLoading(view, url);
/**
* JS调用android原生方法2:
*
* 通过WebViewClient shouldOverrideUrlLoading方法回调拦截url
*
* 根据协议的参数,判断是否是所需要的url:
* 一般根据scheme(协议格式),authority(协议名)来判读
*
* @param url
* @return
*/
private boolean resolveShouldLoadLogic(String url)
Uri uri = Uri.parse(url);
if (uri.getScheme().equals("js"))
if (uri.getAuthority().equals("Authority"))
ToastUtil.showToast(APIWebViewActivity.this, "方法2");
return true;
return false;
3、通过WebChromeClient的 onJsPrompt()等方法 ,回调拦截JS对话框prompt()等:
/**
* 是否支持页面中的js输入弹出框
*
* @param view
* @param url
* @param message
* @param defaultValue
* @param result
* @return
*/
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,
JsPromptResult result)
if (resolveJSPrompt(message))
return true;
return super.onJsPrompt(view, url, message, defaultValue, result);
/**
* JS调用android原生方法3:
*
* 通过WebChromeClient的 onJsAlert() onJsConfirm() onJsPrompt() 方法
* 回调拦截JS对话框alert() confirm() prompt()
*/
private boolean resolveJSPrompt(String message)
Uri uri = Uri.parse(message);
if (uri.getScheme().equals("js"))
if (uri.getAuthority().equals("Authority"))
ToastUtil.showToast(APIWebViewActivity.this, "方法3");
return true;
return false;
完整源码:
Js调用Native示例源码-JsToNativeBridgeActivity
二、Native调用WebView的两种方案:
1、loadUrl("javascript:callJS()"):
此方法简洁、效率低。当不需要返回值且对性能要求较低时可以考虑使用:
/**
* Native调用JS方法一:
* 方法简洁、效率低
* 当不需要获取返回值且对性能要求较低时可选择使用。
*/
webView.loadUrl("javascript:callJS()");
2、evaluateJavascript(script,resultCallback):
需4.4以上才可使用,效率高且有返回值:
/**
* Native调用JS方法二:
* 效率高,有返回值(4.4以上系统使用)
*/
webView.evaluateJavascript("javascript:callJS('yao')", new ValueCallback<String>()
@Override
public void onReceiveValue(String value)
//此处为JS返回的结果
Logger.d("value:" + value);
);
完整源码:
Native调用JS示例源码-NativeToJsBridgeActivity
以上是关于H5 与Native的交互方案的主要内容,如果未能解决你的问题,请参考以下文章