zoukankan      html  css  js  c++  java
  • 原生代码和JS交互说明

    原生代码和JS交互说明

    原则

    1.接口不要定义返回值,JS有获取数据需求的情况通过回调函数的方式实现

    2.尽量保证iOS和Android端一致,简化JS端的使用

    iOS端

     

    iOS端目前使用WKWebview加载前端Html。

    JS调用OC接口WKWebView提供了postMessage的机制来让JS调用OC接口:   

    window.webkit.messageHandlers[namespace].postMessage(JSON.stringify(wrap));

    OC回调JS函数[self.webView evaluateJavaScript:js completionHandler:];

    bridge.js为方便JS端调用,在注册了OC方法后,需要再bridge.js中定义好JS函数,例如:   

                   

                   kf.getResourceInfo = function (callBackName) {
    
                      calliOSFunction("kf","getResourceInfo","",callBackName);
    
                   };

    bridge.js 在webview加载页面时会自动注入到页面中,JS端可直接调用这里声明的函数

     

     

    Android端

    Android使用QQ提供的X5内核WebView,但是该WebView在部分情况下可能会退化会系统的WebView内核,考虑到目前我们最低兼容到Android4.2版本,所有前端的代码依然需要考虑兼容Android4.2的WebView

    JS调用Java接口Android端只要调用: webview.addJavascriptInterface(obj, "kf");方法即可将obj对象中被@JavascriptInterface注解的方法提供给JS端调

    Java调用JSwebview.loadUrl("javascript:" + function + "("" + data + "")");通过此方法可以调用JS中的函数,该函数必须在window对象下。

    带回调函数的接口为方便JS端调用,目前要求所有带回调函数的方法,允许传入function对象,如:   

    kf.getResourceInfo = function (callback){ };

    在调用时,调用方式如下:   

    kf.getResourceInfo(function(data){ 

          console.log(data) 

     })

    因为Java端并不能直接使用JS中函数对象,Java提供的接口只能接收String类型的回调函数名,所以为了支持在前端这样调用,需要做如下的处理

    bridge.js和iOS端一样,带回调的JS接口需要再bridge.js中重新声明, 在assets下的android_bridge.js中:

    kf.getResourceInfo = function(callback){

     win.kf._getResourceInfo(wrapCallback("getResourceInfo", callback));

     };

    和iOS端不同的时,Android端仅需要重新声明带回调函数的方法,无返回值的不需要重新声明

    @CallbackFunction注解请注意上面bridge.js中出现的 _getResourceInfo 方法调用,该方法在Java的接口中并不存在,它是在编译的时候自动生成的,实际的Java方法声明如下:    public class DetailJsFunction extends BaseJsFunction {

    @CallbackFunction

     public void getResourceInfo(final String callback) {

                    webView.callJsFunction(callback, resourceInfo);

               }

     }

    所有被@CallbackFunction注解的方法,在编译时,会自动生成一个新的代理类,该代理类中会自动追加一个 "_" + 原方法名的方法,所以在JS中可以直接以:

     win.kf._getResourceInfo(wrapCallback("getResourceInfo", callback));的方式调用

    使用JsFunctionProxy为了使上述方式生效,需要通过JsFunctionProxy来创建要注入给JS的对象, 如下:    detailJsFunction = JsFunctionProxy.inject(DetailJsFunction.class, this, webView);

      webView.injectJsObject(detailJsFunction, "kf");这里的DetailJsFunction不能是内部类了,必须是public的独立类,所以有些情况可能会略有不便

    其他

    1.除了上述两种原生和JS交互方案,Android和iOS都可以通过拦截特定的scheme的方式来和JS通信,这种方式效率较低,但是最通用,有兴趣的同学可自行搜索相关资料。

    2.Android和iOS的bridge.js代码目前还需要手动维护,但是其实都是可以自动生成的,有兴趣的同学可以搞一下。

    3.Android端的实现现在有点复杂,有兴趣的同学可以去了解下Java编译时代码生成。

     

    /*
    H5和iOS 客户端交互问题总结
    1.Control + Alt + T 【让标签包裹一段内容】
    2.直接返回值/回调【设置】
    3.iOS 注入的时机
    4.客户端调用JS的过程
    【A:Objective-C调H5、B:H5调Objective-C】
    5.客户端/前端自测->Remote device
    6.JS 传参数文档说明
    7.多次点击会重复调用客户端方法
    8.交互过程中的细节问题未考虑
    9.Android 方法名的下划线问题
    10.难以判断出现的问题
    11.浏览器的兼容性问题
    12.:ResultType  Json kit
    
    WebStorm :
    *Remote Devices  {Android}
    *W2 代理
    *自测模板页
    *自升级HTML
    *加载WebView动画
    */

     

     

     

     

  • 相关阅读:
    Web服务器推送技术【转】
    [转]vs2010 中文版下载地址及可用CDKEY
    [php] sae上的一个应用框架申请通过了
    [linux] ssh WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 问题解决
    [php] 调试利器
    [javascript] 邮箱&&电话正则
    [erlang] Erlang比较运算符 (Term Comparisons)
    [vim] gvim 折行
    [linux] 查看内存型号
    [linux] mtu查看&&设置
  • 原文地址:https://www.cnblogs.com/StevenHuSir/p/9723630.html
Copyright © 2011-2022 走看看