Native/JS交互方案

Native/JS交互方案

标签(空格分隔): Hybird


1. 方案一 scheme拦截(JSBridge)

客户端通拦截H5的url,判定之后执行约定的逻辑。


JSBridge方案流程图
JSBridge方案流程图

1.1 使用方法

1.创建全局桥对象jsBridge

2.js向native注册js方法。
Android:jsBridge.registerHandler(String funcName,Function func)
iOS :` [_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) {

responseCallback(@"Response from testObjcCallback");
}];`

3.JS调用Native。
Android: jsBridge.callHandler(String funName,JSON data,Function callbackFunc)

iOS :` [_bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }];

4.native拦截调用

  • Android在shouldOverrideUrlLoading中捕获url。

  • iOS在shouldStartLoadWithRequest中捕获url。

5.url的参数格式
需要解析api名、api使用的参数、回调函数id等。

6.native回调js的参数
封装成JSON格式回调,比如
{ "callbackKey": "key", "callbackData": "data" }
然后通过jsBridge通知H5页面回调。

7.Native调用js
jsBridge._handleMessageFromNative(JSON params)
通过JSON中的数据格式区分是回调还是主动调用。

  • 比如主动调用就是
    { "handlerKey": "key", "handlerData": "data" }
  • 回调就是
    { "callbackKey": "key", "callbackData": "data" }

1.2 优点

  • 兼容性好,适配各个系统版本,Android和iOS通用。
  • 实现简单,容错率高。
  • 兼容现有方案,需少量修改。

1.2 缺点

  • 现存flowpayjsflowpay两套协议。
  • 现存的native调用js方式需要修改(原为loadUrl("javascript:params"))。

1.3 最终调用流程

最终调用流程
最终调用流程

2. 方案二 Native向JS注入对象

Native在适当的时机向浏览器注入jsInterface对象,所有通过此浏览器打开的网页均能使用该对象提供提供的native能力。

2.1 使用方法

1.鉴权并注入jsInterface对象。
webview.addJavascriptInterface(Object jsInterface,String objName);

2.js调用native能力。
window.jsInterface.xxx(params);
结果分文同步和异步返回。

2.1 同步返回可以直接拿到结果。`result=window.jsInterface.xxx(params);`

2.2 异步返回需要重新加载页面传入参数;或者调用约定好的js方法。

3.native调用js能力

  • Android。

4.4版本之前用webview.loadUrl("javascript:(params)");。会刷新页面。无返回值,如果要求返回结果,需要H5页面异步回调。

4.4版本之后用webview.evaluateJavascript("javascript:params",Callback callback);。在callback中可以获取js的返回结果。

  • iOS

WKWebview 使用
(void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler
结果异步返回,目前Stack Overflow上有使用category添加一个同步的返回函数,该函数就用while()不断的轮询,对UI界面有影响,有可能会卡住。

2.2 优点

  • 使用简单。有业务变更时native端只负责提供能力。

2.3 缺点

  • Android在4.2版本以下有webview远程执行js漏洞。可以参考这里
  • 在js里,两端的调用方式不同,需要区分。也可能是有统一的写法但我不知道。

3. 通过Webkit弹窗通知的回调实现交互

通过webChromeClientonJsAlert()onJsConfirm()onJsPrompt()方法回调拦截JS对话框alert()confirm()prompt()消息

3.1 使用方法

JS对话框方法

1.js调用prompt方法

unction clickprompt(){
    // 调用prompt()
    var result=prompt("js://demo?params");
    alert("demo " + result);

2.在客户端的WebChromeClient()重写onJsPrompt()

  public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
        // 根据协议的参数,判断是否是所需要的url
        // 一般根据scheme(协议格式) & authority(协议名)判断(前两个参数)
        Uri uri = Uri.parse(message);
        if (uri.getScheme().equals("js")) {
            if (uri.getAuthority().equals("demo")) {
                // 执行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);
    }

3.2 优点

  • 本质也是协议拦截,不存在兼容性问题。

3.3 缺点

  • native层面与现有的协议不兼容,需要重做。

4. 总结

js交互方案总结

参考

Carson_Ho-最全面总结 Android WebView与 JS 的交互方式
不会写代码的IT男-WebView 安全之 addJavascriptInterface
lzyzsd-JsBridge

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容