zoukankan      html  css  js  c++  java
  • xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

    jsbridge 原理 & 通信原理

    Hybrid 方案是基于 WebView 的,JavaScript 执行在 WebView 的 Webkit 引擎中;
    因此,Hybrid 方案中 JSBridge 的通信原理会具有一些 Web 特性;

    JavaScript 调用 Native

    JavaScript 调用 Native 的方式,主要有两种:

    1. 注入 API
    2. 拦截 URL SCHEME

    注入 API 方式的主要原理是,通过 WebView 提供的接口,向 JavaScript 的 Context(window)中注入对象或者方法,
    让 JavaScript 调用时,直接执行相应的 Native 代码逻辑,达到 JavaScript 调用 Native 的目的;

    iOS 的 UIWebView

    // C++
    
    JSContext *context = [uiWebView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    
    context[@"postBridgeMessage"] = ^(NSArray<NSArray *> *calls) {
        // Native 逻辑
    };
    
    
    
    
    // 前端调用方式
    
    window.postBridgeMessage(message);
    
    

    iOS 的 WKWebView

    // C++
    
    @interface WKWebVIewVC ()<WKScriptMessageHandler>
    
    @implementation WKWebVIewVC
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        WKWebViewConfiguration* configuration = [[WKWebViewConfiguration alloc] init];
        configuration.userContentController = [[WKUserContentController alloc] init];
        WKUserContentController *userCC = configuration.userContentController;
        // 注入对象,前端调用其方法时,Native 可以捕获到
        [userCC addScriptMessageHandler:self name:@"nativeBridge"];
    
        WKWebView wkWebView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];
    
        // TODO 显示 WebView
    }
    
    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
        if ([message.name isEqualToString:@"nativeBridge"]) {
            NSLog(@"前端传递的数据 %@: ",message.body);
            // Native 逻辑
        }
    }
    
    
    
    // 前端调用方式
    
    window.webkit.messageHandlers.nativeBridge.postMessage(message);
    
    

    Android 的 WebView

    // java
    
    publicclassJavaScriptInterfaceDemoActivityextendsActivity{
    private WebView Wv;
    
        @Override
        publicvoidonCreate(Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
    
            Wv = (WebView)findViewById(R.id.webView);     
            final JavaScriptInterface myJavaScriptInterface = new JavaScriptInterface(this);    	 
    
            Wv.getSettings().setJavaScriptEnabled(true);
            Wv.addJavascriptInterface(myJavaScriptInterface, "nativeBridge");
    
            // TODO 显示 WebView
    
        }
    
        publicclassJavaScriptInterface{
             Context mContext;
    
             JavaScriptInterface(Context c) {
                 mContext = c;
             }
    
             publicvoidpostMessage(String webMessage){	    	
                 // Native 逻辑
             }
         }
    }
    
    
    
    //  前端调用方式
    
    window.nativeBridge.postMessage(message);
    
    
    

    拦截 URL SCHEME

    URL SCHEME:URL SCHEME是一种类似于url的链接,是为了方便app直接互相调用设计的,形式和普通的 url 近似,主要区别是 protocol 和 host 一般是自定义的;
    例如: qunarhy://hy/url?url=ymfe.tech,protocol 是 qunarhy,host 则是 hy;

    拦截 URL SCHEME 的主要流程是:
    Web 端通过某种方式(例如 iframe.src)发送 URL Scheme 请求,之后 Native 拦截到请求并根据 URL SCHEME(包括所带的参数)进行相关操作;

    1. 使用 iframe.src 发送 URL SCHEME 会有 url 长度的隐患

    2. 创建请求,需要一定的耗时,比注入 API 的方式调用同样的功能,耗时会较长;

    3. 为什么选择 iframe.src 不选择 locaiton.href ?因为如果通过 location.href 连续调用 Native,很容易丢失一些调用;

    4. 有些方案为了规避 url 长度隐患的缺陷,在 iOS 上采用了使用 Ajax 发送同域请求的方式,并将参数放到 head 或 body 里;
      这样,虽然规避了 url 长度的隐患,但是 WKWebView 并不支持这样的方式;

    Native 调用 JavaScript

    相比于 JavaScript 调用 Native, Native 调用 JavaScript 较为简单,毕竟不管是 iOS 的 UIWebView 还是 WKWebView,还是 Android 的 WebView 组件,
    都以子组件的形式存在于 View/Activity 中,直接调用相应的 API 即可;

    Native 调用 JavaScript,其实就是执行拼接 JavaScript 字符串,从外部调用 JavaScript 中的方法,因此 JavaScript 的方法必须在全局的 window 上;
    (闭包里的方法,JavaScript 自己都调用不了,更不用想让 Native 去调用了)

    iOS 的 UIWebView

    result = [uiWebview stringByEvaluatingJavaScriptFromString:javaScriptString];
    
    
    

    iOS 的 WKWebView

    [wkWebView evaluateJavaScript:javaScriptString completionHandler:completionHandler];
    
    
    

    Android 的 WebView

    Android,在 Kitkat(4.4)之前并没有提供 iOS 类似的调用方式,只能用 loadUrl 一段 JavaScript 代码;
    使用 loadUrl 的方式,并不能获取 JavaScript 执行后的结果;

    webView.loadUrl("javascript:" + javaScriptString);
    
    
    

    Kitkat 之后的版本,也可以用 evaluateJavascript 方法实现

    
    webView.evaluateJavascript(javaScriptString, new ValueCallback<String>() {
        @Override
        publicvoidonReceiveValue(String value){
    
        }
    });
    
    
    
    

    conclusion

    1. JavaScript 调用 Native 推荐使用 注入 API 的方式(iOS6 忽略,Android 4.2以下使用 WebViewClient 的 onJsPrompt 方式)

    2. Native 调用 JavaScript 则直接执行拼接好的 JavaScript 代码即可;

    refs

    https://juejin.im/post/5abca877f265da238155b6bc

    https://www.viseator.com/2018/09/07/android_JSBridge/

    http://coolnuanfeng.github.io/jsbridge

    https://www.jianshu.com/p/910e058a1d63

    https://github.com/lzyzsd/JsBridge

    https://github.com/jacin1/JsBridge

    Native vs Hybrid

    App Development

    https://www.sitepoint.com/native-vs-hybrid-app-development/

    Hybrid applications are web applications (or web pages) in the native browser;

    1. such as UIWebView in iOS
    2. and WebView in Android
    3. (not Safari or Chrome).

    https://www.telerik.com/blogs/what-is-a-hybrid-mobile-app-

    Cordova (formerly PhoneGap)

    https://cordova.apache.org/

    https://github.com/apache?utf8=✓&q=cordova-

    https://www.phonegap.com/

    https://github.com/phonegap/

    Flutter & React Native & Ionic

    https://www.websoptimization.com/blog/hybrid-mobile-app-frameworks/

    JsBridge

    原生开发可以访问平台所有功能,而混合开发中,H5 代码是运行在 WebView 中,而 WebView 实质上就是一个浏览器内核,其 JavaScript 依然运行在一个权限受限的沙箱中,所以对于大多数系统能力都没有访问权限,如无法访问文件系统、不能使用蓝牙等。
    所以,对于 H5 不能实现的功能,都需要原生去做。
    而混合框架一般都会在原生代码中预先实现一些访问系统能力的 API, 然后暴露给 WebView 以供J avaScript调用,这样一来,WebView 就成为了 JavaScript与原生 API之间通信的桥梁,主要负责 JavaScript与原生之间传递调用消息,而消息的传递必须遵守一个标准的协议,它规定了消息的格式与含义,我们把依赖于 WebView的用于在J avaScript与原生之间通信并实现了某种消息传输协议的工具称之为 WebView JavaScript Bridge, 简称 JsBridge,它也是混合开发框架的核心。

    WebView Scheme / URL Scheme

    https://book.flutterchina.club/chapter1/mobile_development_intro.html

    refs



    ©xgqfrms 2012-2020

    www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!


  • 相关阅读:
    leetcode 70 Climbing Stairs
    leetcode 203 Remove Linked List Elements
    【HMM】
    【设计总结】
    【docker】导出导入容器
    【设计工具】样机图
    【设计细节】apple sound
    【产品分析】盒马生鲜 套路
    【喂到嘴经济】这个词有点意思
    【需求分类】KANO模型
  • 原文地址:https://www.cnblogs.com/xgqfrms/p/11422855.html
Copyright © 2011-2022 走看看