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 发布文章使用:只允许注册用户才可以访问!


  • 相关阅读:
    从零开始入门 K8s | 应用编排与管理
    209. Minimum Size Subarray Sum
    208. Implement Trie (Prefix Tree)
    207. Course Schedule
    203. Remove Linked List Elements
    183. Customers Who Never Order
    182. Duplicate Emails
    181. Employees Earning More Than Their Managers
    1261. Find Elements in a Contaminated Binary Tree
    1260. Shift 2D Grid
  • 原文地址:https://www.cnblogs.com/xgqfrms/p/11422855.html
Copyright © 2011-2022 走看看